home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / fmt200.zip / FMT.ASM < prev    next >
Assembly Source File  |  1993-02-07  |  112KB  |  3,983 lines

  1. ;***********************************************************************
  2. ;*                                                                     *
  3. ;*  Fmt.asm                                               07-FEB-1993  *
  4. ;*                                                                     *
  5. ;*  Format Floppy Disk - version 2.00 - MS-DOS 5.0 style format        *
  6. ;*                                                                     *
  7. ;*  Designed for use with IBM AT compatible sytems (including PS/2s)   *
  8. ;*                                                                     *
  9. ;***********************************************************************
  10. ;*                                                                     *
  11. ;*  Developed under MS-DOS version 5.00                                *
  12. ;*                                                                     *
  13. ;*  Compiled with Borland Turbo Assembler version 3.1                  *
  14. ;*                                                                     *
  15. ;*  Linked with Borland Turbo Link version 5.22b                       *
  16. ;*                                                                     *
  17. ;***********************************************************************
  18. ;*                                                                     *
  19. ;*  Syntax: FMT d: size [V] [S] [D] [N|R] [U] [C]                      *
  20. ;*                                                                     *
  21. ;*    where: d = drive (A or B), size = floppy size in Kb,             *
  22. ;*                                                                     *
  23. ;*      the optional V enables format verification, the optional S     *
  24. ;*                                                                     *
  25. ;*      copies the system files, the optional D enables the enhanced   *
  26. ;*                                                                     *
  27. ;*      DOS compatibility mode, the optional N bypasses the prompt,    *
  28. ;*                                                                     *
  29. ;*      the optional R enables recursive formatting with prompting,    *
  30. ;*                                                                     *
  31. ;*      the optional C enables the 720K 1 sector per cluster option,   *
  32. ;*                                                                     *
  33. ;*      and the optional U creates a UNIX disk (F6h fills entire disk) *
  34. ;*                                                                     *
  35. ;*    supported sizes are:                                             *
  36. ;*                                                                     *
  37. ;*      360 for a 360 Kb floppy in a 360 Kb or 1.2 Mb drive            *
  38. ;*      720 for a 720 Kb floppy in a 720 Kb, 1.44 Mb, or 2.88 Mb drive *
  39. ;*      1200 for a 1.2 Mb floppy in a 1.2 Mb drive                     *
  40. ;*      1440 for a 1.44 Mb floppy in a 1.44 Mb  or 2.88 Mb drive       *
  41. ;*      2880 for a 2.88 Mb floppy in a 2.88 Mb drive                   *
  42. ;*                                                                     *
  43. ;***********************************************************************
  44. ;*                                                                     *
  45. ;*  Exit codes:                                                        *
  46. ;*                                                                     *
  47. ;*    0 = successful format                                            *
  48. ;*    1 = failure during format, verify, or write                      *
  49. ;*    2 = disk size / drive type combination is not supported          *
  50. ;*    3 = requested drive does not exist                               *
  51. ;*    4 = invalid or null command line                                 *
  52. ;*    5 = system files not found or error writing system files         *
  53. ;*    6 = computer is not AT compatible                                *
  54. ;*    7 = insufficient memory for file copy buffer (system transfer)   *
  55. ;*    8 = insufficient stack space for program                         *
  56. ;*    9 = program aborted by user (Control-C, Break, or Escape)        *
  57. ;*   10 = unknown drive type (CMOS says floppy type is greater than 5) *
  58. ;*   11 = memory allocation error (while attempting to reduce memory)  *
  59. ;*   12 = both N and R options specified (only one allowed)            *
  60. ;*   13 = 720K option secified, but not 720K format                    *
  61. ;*                                                                     *
  62. ;***********************************************************************
  63. ;*                                                                     *
  64. ;*  In order to use the system transfer option, the following files    *
  65. ;*                                                                     *
  66. ;*    must be present in the root diectory of the default drive:       *
  67. ;*                                                                     *
  68. ;*      1: IBMBIO.COM or IO.SYS (normally a hidden file)               *
  69. ;*                                                                     *
  70. ;*      2: IBMDOS.COM or MSDOS.SYS (normally a hidden file)            *
  71. ;*                                                                     *
  72. ;*      3: COMMAND.COM                                                 *
  73. ;*                                                                     *
  74. ;***********************************************************************
  75. ;*                                                                     *
  76. ;*  Compile with Borland Turbo Assembler(R) version 1.0 or greater     *
  77. ;*                                                                     *
  78. ;*      tasm /t fmt                     tasm /t /zi fmt                *
  79. ;*                              or                                     *
  80. ;*      tlink /t /x fmt                 tlink /v /x fmt                *
  81. ;*                                                                     *
  82. ;*                                      tdstrip -c -s fmt              *
  83. ;*                                                                     *
  84. ;*                                      for use with Turbo Debugger(R) *
  85. ;*    or                                                               *
  86. ;*                                                                     *
  87. ;*  Compile with Microsoft(R) Macro Assembler version 5.0 or greater   *
  88. ;*                                                                     *
  89. ;*      masm /t fmt;                                                   *
  90. ;*                                                                     *
  91. ;*      link fmt;                                                      *
  92. ;*                                                                     *
  93. ;*      exe2bin fmt fmt.com                                            *
  94. ;*                                                                     *
  95. ;*      del fmt.exe                                                    *
  96. ;*                                                                     *
  97. ;***********************************************************************
  98. ;*                                                                     *
  99. ;*  Written by:                                                        *
  100. ;*                                                                     *
  101. ;*  Clair Alan Hardesty                                                *
  102. ;*  Design Validation Engineer II                                      *
  103. ;*  Silicon Systems, Inc.                                              *
  104. ;*  138 New Mohawk Road                                                *
  105. ;*  Nevada City, CA 95959-3262                                         *
  106. ;*                                                                     *
  107. ;*  TEL : (916) 478-8201                                               *
  108. ;*  FAX : (916) 478-8251                                               *
  109. ;*                                                                     *
  110. ;***********************************************************************
  111. ;*                                                                     *
  112. ;*  Microsoft(R) is a registered trademark of Microsoft Corporation    *
  113. ;*                                                                     *
  114. ;*  IBM(R) and PS/2 are registered trademarks of International         *
  115. ;*                                                                     *
  116. ;*   Business Machines Corporation                                     *
  117. ;*                                                                     *
  118. ;*  Turbo Assembler(R) and Turbo Debugger(R) are registered trademarks *
  119. ;*                                                                     *
  120. ;*   of Borland International                                          *
  121. ;*                                                                     *
  122. ;***********************************************************************
  123. ;*                                                                     *
  124. ;*  Revision history:                                                  *
  125. ;*                                                                     *
  126. ;*    Version 1.00 : 23-JAN-1990                                       *
  127. ;*                                                                     *
  128. ;*      Initial public release                                         *
  129. ;*                                                                     *
  130. ;*    Version 1.10 : 03-FEB-1990                                       *
  131. ;*                                                                     *
  132. ;*      Fixed MASM bugs                                                *
  133. ;*                                                                     *
  134. ;*      Added MASM version 5.0 compatibility                           *
  135. ;*                                                                     *
  136. ;*      Improved compatibility for drive type determination            *
  137. ;*                                                                     *
  138. ;*      Added a break handler and `user abort' message                 *
  139. ;*                                                                     *
  140. ;*      Added some new exit codes                                      *
  141. ;*                                                                     *
  142. ;*      Improved the boot record code                                  *
  143. ;*                                                                     *
  144. ;*    Version 1.20 : 10-JUL-1990                                       *
  145. ;*                                                                     *
  146. ;*      Fixed serial number generation to match IBM format exactly     *
  147. ;*                                                                     *
  148. ;*      Fixed system file transfer to work with IBM or Microsoft DOS   *
  149. ;*                                                                     *
  150. ;*      Modified the user abort code to accept the ESCAPE, CONTROL-C,  *
  151. ;*                                                                     *
  152. ;*        or BREAK keys, and fixed some bugs in the user abort code    *
  153. ;*                                                                     *
  154. ;*      Added recursive formatting capability                          *
  155. ;*                                                                     *
  156. ;*    Version 1.30 : 22-DEC-1990                                       *
  157. ;*                                                                     *
  158. ;*      Comment clarifications                                         *
  159. ;*                                                                     *
  160. ;*      Minor code improvements                                        *
  161. ;*                                                                     *
  162. ;*    Version 1.40 : 21-JUN-1991                                       *
  163. ;*                                                                     *
  164. ;*      Improved compatibility for some machines (mainly PS/2s)        *
  165. ;*                                                                     *
  166. ;*    Version 1.50 : 28-FEB-1992                                       *
  167. ;*                                                                     *
  168. ;*      Upgraded to MS-DOS 5.0 with support for 2.88 Mb floppy drives  *
  169. ;*                                                                     *
  170. ;*      Fixed a bug in the reset subroutine retry code                 *
  171. ;*                                                                     *
  172. ;*    Version 1.60 : 09-MAR-1992                                       *
  173. ;*                                                                     *
  174. ;*      Fixed a bug in the format subroutine that caused some machines *
  175. ;*      (COMPAQs) to fail verification. Thanks to Ralph Riggs for      *
  176. ;*      pointing out this bug and assisting in it's eradication.       *
  177. ;*                                                                     *
  178. ;*    Version 1.70 : 01-NOV-1992                                       *
  179. ;*                                                                     *
  180. ;*      Fixed a bug in the stack check code.                           *
  181. ;*      Added the UNIX format option.                                  *
  182. ;*      Removed the copyright - released to the public domain          *
  183. ;*                                                                     *
  184. ;*    Version 2.00 : 07-FEB-1993                                       *
  185. ;*                                                                     *
  186. ;*      added 720 Kb floppy 1 sector per cluster option                *
  187. ;*                                                                     *
  188. ;***********************************************************************
  189.  
  190. ;***********************************************************************
  191.  
  192.                 ; program equates
  193.  
  194. ;***********************************************************************
  195.  
  196. TRUE            equ     01h
  197. FALSE           equ     00h
  198.  
  199. ESC_KEY         equ     011bh
  200. CTRL_C_KEY      equ     2e03h
  201.  
  202. NULL            equ     00h
  203. BACKSPACE       equ     08h
  204. TAB             equ     09h
  205. LF              equ     0ah
  206. CR              equ     0dh
  207. SPACE           equ     20h
  208.  
  209. BOOT            equ     7c00h           ; boot loader base address
  210.  
  211. ;***********************************************************************
  212.  
  213.                 ; set-up for interrupt vector table access
  214.  
  215. ;***********************************************************************
  216.  
  217. seg_zero        segment at 0000h
  218.  
  219.                 assume es:seg_zero
  220.  
  221.                 org 0000h
  222.  
  223. seg_zero        ends
  224.  
  225. ;***********************************************************************
  226.  
  227.                 ; set-up for the far jump used in the boot record code
  228.  
  229. ;***********************************************************************
  230.  
  231. ibmbio          segment at 0070h
  232.  
  233.                 assume cs:ibmbio
  234.  
  235.                 org 0000h
  236.  
  237. program_loader  label far
  238.  
  239. ibmbio          ends
  240.  
  241. ;***********************************************************************
  242.  
  243.                 ; set-up for system identification
  244.  
  245. ;***********************************************************************
  246.  
  247. rom_bios        segment at 0ffffh
  248.  
  249.                 assume ds:rom_bios
  250.  
  251.                 org 000eh
  252.  
  253. system_id       label byte
  254.  
  255. rom_bios        ends
  256.  
  257. ;***********************************************************************
  258.  
  259.                 ; main program code
  260.  
  261. ;***********************************************************************
  262.  
  263. cseg            segment
  264.  
  265.                 assume cs:cseg,ds:cseg,es:cseg,ss:cseg
  266.  
  267.                 org 0100h
  268. entry_point:
  269.                 jmp start               ; skip over data area
  270.  
  271. ;***********************************************************************
  272.  
  273.                 ; format data area
  274.  
  275. ;***********************************************************************
  276.  
  277. BCD_size:       db 4 dup (?)    ; disk size in BCD
  278. binary_size:    dw ?            ; disk size in binary
  279. verify:         db FALSE        ; default is no verification
  280. system:         db FALSE        ; default is no system file transfer
  281. prompt:         db TRUE         ; default is prompt to insert floppy
  282. recurse:        db FALSE        ; default is no recursion
  283. prmt_or_rcrs:   db FALSE        ; used to allow only one of the options
  284. standard:       db FALSE        ; use DOS standard format parameters
  285. cluster_720K:   db FALSE        ; default is 2 sectors per cluster
  286. drive_number:   db ?
  287. disk_drive:     dw ?
  288. max_track:      db ?
  289. retry_count:    db ?
  290. write_track:    dw ?
  291. write_head:     db ?
  292. write_sector:   db ?
  293. cursor:         dw ?
  294. stack_size:     dw 1024         ; minimum allowable stack space
  295. minimum_buffer: dw 4096         ; minimum file copy buffer size
  296. buffer_size:    dw ?            ; actual file copy buffer size
  297. system_exists:  db ?            ; boolean for system on default drive
  298. is_ibm:         db ?            ; boolean for PC-DOS or MS-DOS
  299. unix:           db ?            ; boolean for UNIX format
  300.  
  301.                 ; the reset subroutine needs a dedicated retry count
  302.  
  303. reset_retry_count:      db ?
  304.  
  305. ;***********************************************************************
  306.  
  307. disk_size:      db ?
  308.  
  309.                 ; 1 = 360kb
  310.                 ; 2 = 1.2Mb
  311.                 ; 3 = 720kb
  312.                 ; 4 = 1.44Mb
  313.                 ; 5 = 2.88Mb
  314.  
  315. drive_type:     db ?
  316.  
  317.                 ; 0 = no drive
  318.                 ; 1 = 360kb
  319.                 ; 2 = 1.2Mb
  320.                 ; 3 = 720kb
  321.                 ; 4 = 1.44Mb
  322.                 ; 5 = 2.88Mb
  323.  
  324. ;***********************************************************************
  325.  
  326. stack_pointer:
  327.  
  328.         dw ?    ; storage for initial stack pointer (eases some exits)
  329.  
  330. parameter_pointer:
  331.  
  332.         dd ?    ; storage for the original disk parameter table pointer
  333.  
  334. control_break:
  335.  
  336.         dd ?    ; storage for the original control-break handler vector
  337.  
  338. ;***********************************************************************
  339.  
  340. floppy_table:
  341.                 ; 360 Kb
  342.  
  343.                 db 0FDh         ; media descriptor
  344.                 db 40           ; number of tracks
  345.                 dw 9            ; sectors per track
  346.                 dw 112          ; entries per root directory
  347.                 db 7            ; sectors per root directory
  348.                 db 2            ; sectors per cluster
  349.                 dw 2            ; sectors per FAT
  350.  
  351.                 ; 1.2 Mb
  352.  
  353.                 db 0F9h         ; media descriptor
  354.                 db 80           ; number of tracks
  355.                 dw 15           ; sectors per track
  356.                 dw 224          ; entries per root directory
  357.                 db 14           ; sectors per root directory
  358.                 db 1            ; sectors per cluster
  359.                 dw 7            ; sectors per FAT
  360.  
  361.                 ; 720 Kb - 2 sectors per cluster
  362.  
  363.                 db 0F9h         ; media descriptor
  364.                 db 80           ; number of tracks
  365.                 dw 9            ; sectors per track
  366.                 dw 112          ; entries per root directory
  367.                 db 7            ; sectors per root directory
  368.                 db 2            ; sectors per cluster
  369.                 dw 3            ; sectors per FAT
  370.  
  371.                 ; 1.44 Mb
  372.  
  373.                 db 0F0h         ; media descriptor
  374.                 db 80           ; number of tracks
  375.                 dw 18           ; sectors per track
  376.                 dw 224          ; entries per root directory
  377.                 db 14           ; sectors per root directory
  378.                 db 1            ; sectors per cluster
  379.                 dw 9            ; sectors per FAT
  380.  
  381.                 ; 2.88 Mb
  382.  
  383.                 db 0F0h         ; media descriptor
  384.                 db 80           ; number of tracks
  385.                 dw 36           ; sectors per track
  386.                 dw 240          ; entries per root directory
  387.                 db 15           ; sectors per root directory
  388.                 db 2            ; sectors per cluster
  389.                 dw 9            ; sectors per FAT
  390.  
  391.                 ; 720 Kb - 1 sector per cluster
  392.  
  393.                 db 0F9h         ; media descriptor
  394.                 db 80           ; number of tracks
  395.                 dw 9            ; sectors per track
  396.                 dw 112          ; entries per root directory
  397.                 db 7            ; sectors per root directory
  398.                 db 1            ; sectors per cluster
  399.                 dw 5            ; sectors per FAT
  400.  
  401. ;***********************************************************************
  402.  
  403. parameter_table:                ; enables fast formatting
  404.  
  405.         ; uses some non-standard parameters for improved speed
  406.  
  407.         ; 360 Kb
  408.  
  409.         db 0D2h,002h,009h,002h,009h,02Ah,0FFh,050h,0F6h,001h,001h
  410.  
  411.         ; 1.2 Mb
  412.  
  413.         db 082h,002h,009h,002h,00Fh,01Bh,0FFh,054h,0F6h,001h,001h
  414.  
  415.         ; 720 Kb
  416.  
  417.         db 012h,002h,009h,002h,009h,02Ah,0FFh,050h,0F6h,001h,001h
  418.  
  419.         ; 1.44 Mb
  420.  
  421.         db 012h,002h,009h,002h,012h,01Bh,0FFh,06Ch,0F6h,001h,001h
  422.  
  423.         ; 2.88 Mb
  424.  
  425.         db 012h,002h,009h,002h,024h,01Bh,0FFh,06Ch,0F6h,001h,001h
  426.  
  427. standard_parameter_table:       ; uses DOS standards for compatibility
  428.  
  429.         ; uses DOS standard parameters for compatibility (slower)
  430.  
  431.         ; 360 Kb
  432.  
  433.         db 0DFh,002h,025h,002h,009h,02Ah,0FFh,050h,0F6h,00Fh,008h
  434.  
  435.         ; 1.2 Mb
  436.  
  437.         db 0DFh,002h,025h,002h,00Fh,01Bh,0FFh,054h,0F6h,00Fh,008h
  438.  
  439.         ; 720 Kb
  440.  
  441.         db 0DFh,002h,025h,002h,009h,02Ah,0FFh,050h,0F6h,00Fh,008h
  442.  
  443.         ; 1.44 Mb
  444.  
  445.         db 0AFh,002h,025h,002h,012h,01Bh,0FFh,06Ch,0F6h,00Fh,008h
  446.  
  447.         ; 2.88 Mb
  448.  
  449.         db 0DFh,002h,025h,002h,024h,01Bh,0FFh,06Ch,0F6h,00Fh,008h
  450.  
  451. ;***********************************************************************
  452.  
  453.                 ; format sector tables
  454.  
  455. ;***********************************************************************
  456.  
  457. sector_table_0:
  458.                 db 000h,000h,001h,002h
  459.                 db 000h,000h,002h,002h
  460.                 db 000h,000h,003h,002h
  461.                 db 000h,000h,004h,002h
  462.                 db 000h,000h,005h,002h
  463.                 db 000h,000h,006h,002h
  464.                 db 000h,000h,007h,002h
  465.                 db 000h,000h,008h,002h
  466.                 db 000h,000h,009h,002h
  467.                 db 000h,000h,00Ah,002h
  468.                 db 000h,000h,00Bh,002h
  469.                 db 000h,000h,00Ch,002h
  470.                 db 000h,000h,00Dh,002h
  471.                 db 000h,000h,00Eh,002h
  472.                 db 000h,000h,00Fh,002h
  473.                 db 000h,000h,010h,002h
  474.                 db 000h,000h,011h,002h
  475.                 db 000h,000h,012h,002h
  476.                 db 000h,000h,013h,002h
  477.                 db 000h,000h,014h,002h
  478.                 db 000h,000h,015h,002h
  479.                 db 000h,000h,016h,002h
  480.                 db 000h,000h,017h,002h
  481.                 db 000h,000h,018h,002h
  482.                 db 000h,000h,019h,002h
  483.                 db 000h,000h,01Ah,002h
  484.                 db 000h,000h,01Bh,002h
  485.                 db 000h,000h,01Ch,002h
  486.                 db 000h,000h,01Dh,002h
  487.                 db 000h,000h,01Eh,002h
  488.                 db 000h,000h,01Fh,002h
  489.                 db 000h,000h,020h,002h
  490.                 db 000h,000h,021h,002h
  491.                 db 000h,000h,022h,002h
  492.                 db 000h,000h,023h,002h
  493.                 db 000h,000h,024h,002h
  494.  
  495. sector_table_1:
  496.                 db 000h,001h,001h,002h
  497.                 db 000h,001h,002h,002h
  498.                 db 000h,001h,003h,002h
  499.                 db 000h,001h,004h,002h
  500.                 db 000h,001h,005h,002h
  501.                 db 000h,001h,006h,002h
  502.                 db 000h,001h,007h,002h
  503.                 db 000h,001h,008h,002h
  504.                 db 000h,001h,009h,002h
  505.                 db 000h,001h,00Ah,002h
  506.                 db 000h,001h,00Bh,002h
  507.                 db 000h,001h,00Ch,002h
  508.                 db 000h,001h,00Dh,002h
  509.                 db 000h,001h,00Eh,002h
  510.                 db 000h,001h,00Fh,002h
  511.                 db 000h,001h,010h,002h
  512.                 db 000h,001h,011h,002h
  513.                 db 000h,001h,012h,002h
  514.                 db 000h,001h,013h,002h
  515.                 db 000h,001h,014h,002h
  516.                 db 000h,001h,015h,002h
  517.                 db 000h,001h,016h,002h
  518.                 db 000h,001h,017h,002h
  519.                 db 000h,001h,018h,002h
  520.                 db 000h,001h,019h,002h
  521.                 db 000h,001h,01Ah,002h
  522.                 db 000h,001h,01Bh,002h
  523.                 db 000h,001h,01Ch,002h
  524.                 db 000h,001h,01Dh,002h
  525.                 db 000h,001h,01Eh,002h
  526.                 db 000h,001h,01Fh,002h
  527.                 db 000h,001h,020h,002h
  528.                 db 000h,001h,021h,002h
  529.                 db 000h,001h,022h,002h
  530.                 db 000h,001h,023h,002h
  531.                 db 000h,001h,024h,002h
  532.  
  533. ;***********************************************************************
  534.  
  535.         ; file copy data area
  536.  
  537. ;***********************************************************************
  538.  
  539. ibm_bios_source_path:
  540.  
  541.         db "d:\"
  542.  
  543.     ibm_bios_source_filename:
  544.  
  545.         db "IBMBIO.COM",NULL,BACKSPACE
  546.         db "$"
  547.  
  548. ibm_bios_destination_path:
  549.  
  550.         db "d:\"
  551.  
  552.     ibm_bios_destination_filename:
  553.  
  554.         db "IBMBIO.COM",NULL,BACKSPACE
  555.         db "$"
  556.  
  557. ibm_dos_source_path:
  558.  
  559.         db "d:\"
  560.  
  561.     ibm_dos_source_filename:
  562.  
  563.         db "IBMDOS.COM",NULL,BACKSPACE
  564.         db "$"
  565.  
  566. ibm_dos_destination_path:
  567.  
  568.         db "d:\"
  569.  
  570.     ibm_dos_destination_filename:
  571.  
  572.         db "IBMDOS.COM",NULL,BACKSPACE
  573.         db "$"
  574.  
  575. ms_bios_source_path:
  576.  
  577.         db "d:\"
  578.  
  579.     ms_bios_source_filename:
  580.  
  581.         db "IO.SYS",NULL,BACKSPACE
  582.         db "$"
  583.  
  584. ms_bios_destination_path:
  585.  
  586.         db "d:\"
  587.  
  588.     ms_bios_destination_filename:
  589.  
  590.         db "IO.SYS",NULL,BACKSPACE
  591.         db "$"
  592.  
  593. ms_dos_source_path:
  594.  
  595.         db "d:\"
  596.  
  597.     ms_dos_source_filename:
  598.  
  599.         db "MSDOS.SYS",NULL,BACKSPACE
  600.         db "$"
  601.  
  602. ms_dos_destination_path:
  603.  
  604.         db "d:\"
  605.  
  606.     ms_dos_destination_filename:
  607.  
  608.         db "MSDOS.SYS",NULL,BACKSPACE
  609.         db "$"
  610.  
  611. cmd_source_path:
  612.  
  613.         db "d:\"
  614.  
  615.     cmd_source_filename:
  616.  
  617.         db "COMMAND.COM",NULL,BACKSPACE
  618.         db "$"
  619.  
  620. cmd_destination_path:
  621.  
  622.         db "d:\"
  623.  
  624.     cmd_destination_filename:
  625.  
  626.         db "COMMAND.COM",NULL,BACKSPACE
  627.         db "$"
  628.  
  629. ibm_bios_name:
  630.  
  631.         db "IBMBIO  COM"
  632.  
  633. ibm_dos_name:
  634.  
  635.         db "IBMDOS  COM"
  636.  
  637. ms_bios_name:
  638.  
  639.         db "IO      SYS"
  640.  
  641. ms_dos_name:
  642.  
  643.         db "MSDOS   SYS"
  644.  
  645. ;***********************************************************************
  646.  
  647.         ; informational messages
  648.  
  649. ;***********************************************************************
  650.  
  651. cr_lf:
  652.         db CR,LF
  653.         db "$"
  654.  
  655. insert_floppy:
  656.  
  657.         db "Put desired floppy in drive "
  658.  
  659.     insert_drive:
  660.  
  661.         db ?
  662.         db ": and press any key"
  663.         db "$"
  664.  
  665. initializing:
  666.  
  667.         db "Initializing"
  668.         db "$"
  669.  
  670. clear_line:
  671.  
  672.         db 50 dup (BACKSPACE)
  673.         db 50 dup (SPACE)
  674.         db 50 dup (BACKSPACE)
  675.         db "$"
  676.  
  677. format_display:
  678.  
  679.         db 26 dup (BACKSPACE)
  680.         db "Formatting track "
  681.  
  682.     format_track_number:
  683.  
  684.         db 2 dup (?)
  685.         db " head "
  686.  
  687.     format_head_number:
  688.  
  689.         db ?
  690.         db "$"
  691.  
  692. verify_display:
  693.  
  694.         db 26 dup (BACKSPACE)
  695.         db "Verifying  track "
  696.  
  697.     verify_track_number:
  698.  
  699.         db 2 dup (?)
  700.         db " head "
  701.  
  702.     verify_head_number:
  703.  
  704.         db ?
  705.         db "$"
  706.  
  707. boot_message:
  708.  
  709.         db 26 dup (BACKSPACE)
  710.         db 26 dup (SPACE)
  711.         db 26 dup (BACKSPACE)
  712.         db "Writing boot record"
  713.         db "$"
  714.  
  715. fat_message:
  716.  
  717.         db 19 dup (BACKSPACE)
  718.         db 19 dup (SPACE)
  719.         db 19 dup (BACKSPACE)
  720.         db "Writing FATs"
  721.         db "$"
  722.  
  723. dir_message:
  724.  
  725.         db 12 dup (BACKSPACE)
  726.         db 12 dup (SPACE)
  727.         db 12 dup (BACKSPACE)
  728.         db "Writing root directory"
  729.         db "$"
  730.  
  731. file_copy_message:
  732.  
  733.         db 22 dup (BACKSPACE)
  734.         db 22 dup (SPACE)
  735.         db 22 dup (BACKSPACE)
  736.         db "Copying system files"
  737.         db "$"
  738.  
  739. exit_message:
  740.  
  741.         db 22 dup (BACKSPACE)
  742.         db 22 dup (SPACE)
  743.         db 22 dup (BACKSPACE)
  744.         db "Format complete"
  745.         db CR,LF
  746.         db "$"
  747.  
  748. ;***********************************************************************
  749.  
  750.         ; error messages
  751.  
  752. ;***********************************************************************
  753.  
  754. allocation_error:
  755.  
  756.         db "Memory allocation error"
  757.         db CR,LF
  758.         db "$"
  759.  
  760. no_stack_space:
  761.  
  762.         db "Not enough room for program stack"
  763.         db CR,LF
  764.         db "$"
  765.  
  766. computer_message:
  767.  
  768.         db "IBM AT or compatible computer required"
  769.         db CR,LF
  770.         db "$"
  771.  
  772. no_drive_error:
  773.  
  774.         db "No such drive in system"
  775.         db CR,LF
  776.         db "$"
  777.  
  778. reset_error:
  779.  
  780.         db "Disk controller reset error"
  781.         db CR,LF
  782.         db "$"
  783.  
  784. set_drive_error:
  785.  
  786.         db "Disk drive type not supported by BIOS"
  787.         db CR,LF
  788.         db "$"
  789.  
  790. get_type_error:
  791.  
  792.         db "Unknown drive type"
  793.         db CR,LF
  794.         db "$"
  795.  
  796. no_floppy_error:
  797.  
  798.         db "No floppy in drive"
  799.         db CR,LF
  800.         db "$"
  801.  
  802. set_disk_error:
  803.  
  804.         db "Disk / Drive combination not supported"
  805.         db CR,LF
  806.         db "$"
  807.  
  808. write_boot_error:
  809.  
  810.         db "Error writing boot record"
  811.         db CR,LF
  812.         db "$"
  813.  
  814. write_fat_error:
  815.  
  816.         db "Error writing FAT"
  817.         db CR,LF
  818.         db "$"
  819.  
  820. write_dir_error:
  821.  
  822.         db "Error writing directory"
  823.         db CR,LF
  824.         db "$"
  825.  
  826. write_protect_error:
  827.  
  828.         db "Disk is write protected"
  829.         db CR,LF
  830.         db "$"
  831.  
  832. user_abort:
  833.  
  834.         db "User abort"
  835.         db CR,LF
  836.         db "$"
  837.  
  838. error_during_format:
  839.  
  840.         db "Error during format"
  841.         db CR,LF
  842.         db "$"
  843.  
  844. disk_type_error:
  845.  
  846.         db "Defective floppy or wrong floppy type"
  847.         db CR,LF
  848.         db "$"
  849.  
  850. verify_error:
  851.  
  852.         db "Verification error"
  853.         db CR,LF
  854.         db "$"
  855.  
  856. buffer_space_error:
  857.  
  858.         db "No room for file copy buffer"
  859.         db CR,LF
  860.         db "$"
  861.  
  862. option_error:
  863.  
  864.         db CR,LF
  865.         db "Both N and R options specified (only one allowed)"
  866.         db CR,LF
  867.         db "$"
  868.  
  869. cluster_720K_error:
  870.  
  871.         db CR,LF
  872.         db "720K 1 sector option specified, but not 720K format"
  873.         db CR,LF
  874.         db "$"
  875.  
  876. help_message:
  877.  
  878. db CR,LF
  879. db "FMT version 2.00 : 07-FEB-1993 : Written by Clair Alan Hardesty"
  880. db CR,LF,LF
  881. db " syntax: FMT d: size [V] [S] [D] [N|R] [U] [C]"
  882. db CR,LF,LF
  883. db "  where: d = drive (A or B), size = floppy size in Kb,"
  884. db CR,LF,LF
  885. db "   the optional V enables format verification, the optional S"
  886. db CR,LF,LF
  887. db "   copies the system files, the optional D enables the enhanced"
  888. db CR,LF,LF
  889. db "   DOS compatibility mode, the optional N bypasses the prompt,"
  890. db CR,LF,LF
  891. db "   the optional R enables recursive formatting with prompting,"
  892. db CR,LF,LF
  893. db "   the optional C enables the 720K 1 sector per cluster option,"
  894. db CR,LF,LF
  895. db "   and the optional U creates a UNIX disk (F6h fills entire disk)"
  896. db CR,LF,LF
  897. db "  supported sizes are:"
  898. db CR,LF,LF
  899. db "   360 for a 360 Kb floppy in a 360 Kb or 1.2 Mb drive"
  900. db CR,LF
  901. db "   720 for a 720 Kb floppy in a 720 Kb, 1.44 Mb, or 2.88 Mb drive"
  902. db CR,LF
  903. db "   1200 for a 1.2 Mb floppy in a 1.2 Mb drive"
  904. db CR,LF
  905. db "   1440 for a 1.44 Mb floppy in a 1.44 Mb or 2.88 Mb drive"
  906. db CR,LF
  907. db "   2880 for a 2.88 Mb floppy in a 2.88 Mb drive"
  908. db CR,LF
  909. db "$"
  910.  
  911. ;***********************************************************************
  912.  
  913.                 ; reduce memory allocation and check stack space
  914.  
  915. ;***********************************************************************
  916.  
  917. start:
  918.                 ; if more than 64 Kb is available, then SP => FFFCh
  919.  
  920.                 cmp sp,0fffch
  921.  
  922.                 jl check_stack
  923.  
  924.                 ; reduce memory allocation to 64 Kb
  925.  
  926.                 mov bx,1000h
  927.                 mov ah,4ah
  928.  
  929.                 int 21h
  930.  
  931.                 jnc check_stack
  932.  
  933.                 ; set exit code to 11 (memory allocation error)
  934.  
  935.                 mov dx,offset allocation_error
  936.                 mov ah,09h
  937.  
  938.                 int 21h
  939.  
  940.                 mov ax,4c0bh
  941.  
  942.                 int 21h
  943. check_stack:
  944.                 ; check stack space
  945.  
  946.                 mov ax,sp
  947.                 mov bx,offset file_buffer
  948.                 sub ax,bx
  949.                 cmp ax,word ptr [stack_size]
  950.  
  951.                 ja room_for_stack
  952.  
  953.                 ; set exit code to 9 (not enough room for stack)
  954.  
  955.                 mov dx,offset no_stack_space
  956.                 mov ah,09h
  957.  
  958.                 int 21h
  959.  
  960.                 mov ax,4c08h
  961.  
  962.                 int 21h
  963. room_for_stack:
  964.                 ; save the stack pointer
  965.  
  966.                 mov word ptr [stack_pointer],sp
  967.  
  968. ;***********************************************************************
  969.  
  970.                 ; check cpu and computer type
  971.  
  972. ;***********************************************************************
  973.  
  974.                 ; check CPU for 80286 or above
  975.  
  976.                 push ds
  977.                 xor     ax,ax
  978.                 push    ax
  979.                 popf
  980.                 pushf
  981.                 pop     ax
  982.                 and     ax,8000h
  983.                 cmp     ax,8000h
  984.  
  985.                 je short not_an_at
  986.  
  987.                 ; check the model byte in ROM
  988.  
  989.                 mov ax,rom_bios
  990.                 mov ds,ax
  991.  
  992.                 assume ds:rom_bios
  993.  
  994.                 cmp system_id,0fch      ; AT or compatible
  995.  
  996.                 je at_or_better
  997.  
  998.                 cmp system_id,0fah      ; most 80286 P/S-2 models
  999.  
  1000.                 je at_or_better
  1001.  
  1002.                 cmp system_id,0f8h      ; P/S-2 model 80
  1003.  
  1004.                 je at_or_better
  1005.  
  1006.                 ; additional model identification code goes here
  1007. not_an_at:
  1008.                 ; computer is not AT compatible
  1009.  
  1010.                 pop ds
  1011.  
  1012.                 assume ds:cseg
  1013.  
  1014.                 mov dx,offset computer_message
  1015.                 mov ah,09h
  1016.  
  1017.                 int 21h
  1018.  
  1019.                 ; set exit code to 6 (not an AT or compatible)
  1020.  
  1021.                 mov sp,word ptr [stack_pointer]
  1022.                 mov ax,4c06h
  1023.  
  1024.                 int 21h
  1025. at_or_better:
  1026.  
  1027. ;***********************************************************************
  1028.  
  1029. cseg            ends
  1030.  
  1031. .286            ; enable the 80286 instruction set
  1032.  
  1033. cseg            segment
  1034.  
  1035. ;***********************************************************************
  1036.  
  1037.                 pop ds
  1038.  
  1039.                 assume ds:cseg
  1040.  
  1041.                 ; initialize some variables
  1042.  
  1043.                 mov cl,0                ; parameter counter
  1044.                 mov dl,0                ; disk size digit counter
  1045.                 mov di,offset BCD_size  ; temporary disk size storage
  1046.                 mov bx,0080h            ; pointer to the command line
  1047.  
  1048. ;***********************************************************************
  1049.  
  1050.                 ; parse the command line
  1051.  
  1052. ;***********************************************************************
  1053.  
  1054. parse_loop:
  1055.                 inc bx
  1056.                 cmp byte ptr [bx],CR
  1057.  
  1058.                 jne not_finished
  1059.  
  1060.                 jmp got_command
  1061. not_finished:
  1062.                 cmp byte ptr [bx],SPACE
  1063.  
  1064.                 je parse_loop
  1065.  
  1066.                 cmp byte ptr [bx],TAB
  1067.  
  1068.                 je parse_loop
  1069.  
  1070.                 cmp cl,0
  1071.  
  1072.                 jg number_check
  1073.  
  1074.                 and byte ptr [bx],5fh   ; capitalize drive letter
  1075.  
  1076.                 ; check the drive letter (must be drive A: or B:)
  1077.  
  1078.                 cmp byte ptr [bx],'A'
  1079.  
  1080.                 jnl check_for_b
  1081.  
  1082.                 jmp help                ; invalid drive
  1083. check_for_b:
  1084.                 cmp byte ptr [bx],'B'
  1085.  
  1086.                 jng store_drive
  1087.  
  1088.                 jmp help                ; invalid drive
  1089. store_drive:
  1090.                 mov al,byte ptr [bx]
  1091.                 sub al,'A'
  1092.                 mov byte ptr [drive_number],al
  1093. colon_check:
  1094.                 cmp byte ptr [bx+1],':'
  1095.  
  1096.                 je found_colon
  1097.  
  1098.                 jmp help                ; no colon after drive letter
  1099. found_colon:
  1100.                 inc bx                  ; skip over the colon
  1101.                 inc cl                  ; increment parameter count
  1102.  
  1103.                 jmp parse_loop
  1104. number_check:
  1105.                 cmp cl,1
  1106.  
  1107.                 jg check_option
  1108.  
  1109.                 cmp byte ptr [bx],'0'
  1110.  
  1111.                 jnl maybe_a_number
  1112.  
  1113.                 jmp help                ; not a number
  1114. maybe_a_number:
  1115.                 cmp byte ptr [bx],'9'
  1116.  
  1117.                 jng is_a_number
  1118.  
  1119.                 jmp help                ; not a number
  1120. is_a_number:
  1121.                 ; check for last digit by looking at next character
  1122.  
  1123.                 cmp byte ptr [bx+1],CR
  1124.  
  1125.                 je last_digit
  1126.  
  1127.                 cmp byte ptr [bx+1],SPACE
  1128.  
  1129.                 je last_digit
  1130.  
  1131.                 cmp byte ptr [bx+1],TAB
  1132.  
  1133.                 jne store_digit
  1134. last_digit:
  1135.                 inc cl                  ; increment parameter count
  1136. store_digit:
  1137.                 mov al,byte ptr [bx]
  1138.                 sub al,'0'              ; convert ASCII to BCD
  1139.                 mov byte ptr [di],al    ; store BCD digit in BCD_size
  1140.                 inc di                  ; increment storage pointer
  1141.                 inc dl                  ; increment digit count
  1142.                 cmp dl,5                ; check digit count
  1143.  
  1144.                 jl jump_to_parse        ; less than 5 digits
  1145.  
  1146.                 jmp help                ; too many digits in disk size
  1147. jump_to_parse:
  1148.                 jmp parse_loop          ; continue parsing parameters
  1149. check_option:
  1150.                 cmp cl,8
  1151.  
  1152.                 jl parse_option         ; less than 8 parameters ?
  1153.  
  1154.                 jmp help                ; too many parameters
  1155. parse_option:
  1156.                 and byte ptr [bx],5fh
  1157.                 cmp byte ptr [bx],'V'   ; check for verify option
  1158.  
  1159.                 je set_verify
  1160.  
  1161.                 cmp byte ptr [bx],'S'   ; check for system option
  1162.  
  1163.                 je set_system
  1164.  
  1165.                 cmp byte ptr [bx],'N'   ; check for skip prompt option
  1166.  
  1167.                 je clear_prompt
  1168.  
  1169.                 cmp byte ptr [bx],'R'   ; check for recursion option
  1170.  
  1171.                 je set_recursion
  1172.  
  1173.                 cmp byte ptr [bx],'D'   ; check for standard option
  1174.  
  1175.                 je set_standard
  1176.  
  1177.                 cmp byte ptr [bx],'U'   ; check for UNIX option
  1178.  
  1179.                 je set_unix
  1180.  
  1181.                 cmp byte ptr [bx],'C'   ; check for 720K option
  1182.  
  1183.                 je set_cluster
  1184.  
  1185.                 jmp help                ; invalid option
  1186. set_verify:
  1187.                 mov byte ptr [verify],1 ; set format verify true
  1188.                 inc cl
  1189.  
  1190.                 jmp parse_loop
  1191. set_standard:
  1192.                 mov byte ptr [standard],1 ; set standard parameters true
  1193.                 inc cl
  1194.  
  1195.                 jmp parse_loop
  1196. set_unix:
  1197.                 mov byte ptr [unix],1   ; set UNIX format option true
  1198.                 inc cl
  1199.  
  1200.                 jmp parse_loop
  1201. set_cluster:
  1202.                 mov byte ptr [cluster_720K],1 ; set 720K option true
  1203.                 inc cl
  1204.  
  1205.                 jmp parse_loop
  1206. set_system:
  1207.                 mov byte ptr [system],1 ; set transfer system true
  1208.                 inc cl
  1209.  
  1210.                 jmp parse_loop
  1211. clear_prompt:
  1212.                 cmp byte ptr [prmt_or_rcrs],FALSE
  1213.  
  1214.                 je prompt_ok
  1215. exclusive:
  1216.                 ; mutually exclusive options specified
  1217.  
  1218.                 mov dx,offset option_error
  1219.                 mov ah,09h
  1220.  
  1221.                 int 21h
  1222.  
  1223.                 ; set exit code to 12 (mutually exclusive options)
  1224.  
  1225.                 mov sp,word ptr [stack_pointer]
  1226.                 mov ax,4c0ch
  1227.  
  1228.                 int 21h
  1229. prompt_ok:
  1230.                 mov byte ptr [prmt_or_rcrs],TRUE
  1231.                 mov byte ptr [recurse],FALSE
  1232.                 mov byte ptr [prompt],FALSE
  1233.                 inc cl
  1234.  
  1235.                 jmp parse_loop
  1236. set_recursion:
  1237.                 cmp byte ptr [prmt_or_rcrs],FALSE
  1238.  
  1239.                 je recurse_ok
  1240.  
  1241.                 jmp exclusive
  1242. recurse_ok:
  1243.                 mov byte ptr [prmt_or_rcrs],TRUE
  1244.                 mov byte ptr [recurse],TRUE
  1245.                 mov byte ptr [prompt],TRUE
  1246.                 inc cl
  1247.  
  1248.                 jmp parse_loop
  1249. got_command:
  1250.                 cmp cl,2
  1251.  
  1252.                 jnl two_parameters
  1253.  
  1254.                 jmp help                ; too few parameters
  1255. two_parameters:
  1256.                 cmp dl,3
  1257.  
  1258.                 jge three_digits
  1259.  
  1260.                 jmp help                ; too few digits in disk size
  1261. three_digits:
  1262.                 ; convert the disk size parameter from BCD to binary
  1263.  
  1264.                 mov cl,dl
  1265.                 dec di
  1266.                 xor ah,ah
  1267.                 mov al,byte ptr [di]
  1268.                 mov word ptr [binary_size],ax
  1269.                 dec di
  1270.                 dec cl
  1271.                 xor ah,ah
  1272.                 mov al,byte ptr [di]
  1273.                 imul ax,10
  1274.                 add word ptr [binary_size],ax
  1275.                 dec di
  1276.                 dec cl
  1277.                 xor ah,ah
  1278.                 mov al,byte ptr [di]
  1279.                 imul ax,100
  1280.                 add word ptr [binary_size],ax
  1281.                 dec di
  1282.                 dec cl
  1283.  
  1284.                 jz test_size_360
  1285.  
  1286.                 xor ah,ah
  1287.                 mov al,byte ptr [di]
  1288.                 imul ax,1000
  1289.                 add word ptr [binary_size],ax
  1290. test_size_360:
  1291.                 cmp word ptr [binary_size],360
  1292.  
  1293.                 jne test_size_1200              ; not 360 Kb
  1294.  
  1295.                 mov byte ptr [disk_size],1
  1296.  
  1297.                 jmp short set_up                ; command line is valid
  1298. test_size_1200:
  1299.                 cmp word ptr [binary_size],1200
  1300.  
  1301.                 jne test_size_720               ; not 1.2 Mb
  1302.  
  1303.                 mov byte ptr [disk_size],2
  1304.  
  1305.                 jmp short set_up                ; command line is valid
  1306. test_size_720:
  1307.                 cmp word ptr [binary_size],720
  1308.  
  1309.                 jne test_size_1440              ; not 720 Kb
  1310.  
  1311.                 mov byte ptr [disk_size],3
  1312.  
  1313.                 jmp short set_up                ; command line is valid
  1314. test_size_1440:
  1315.                 cmp word ptr [binary_size],1440
  1316.  
  1317.                 jne test_size_2880              ; not 1.44 Mb
  1318.  
  1319.                 mov byte ptr [disk_size],4
  1320.  
  1321.                 jmp short set_up                ; command line is valid
  1322. test_size_2880:
  1323.                 cmp word ptr [binary_size],2880
  1324.  
  1325.                 jne help                        ; not 2.88 Mb
  1326.  
  1327.                 mov byte ptr [disk_size],5
  1328.  
  1329.                 jmp short set_up                ; command line is valid
  1330. help:
  1331.                 ; command line is invalid or null
  1332.  
  1333.                 mov dx,offset help_message
  1334.                 mov ah,09h
  1335.  
  1336.                 int 21h
  1337.  
  1338.                 ; set exit code to 4 (null or invalid command line)
  1339.  
  1340.                 mov sp,word ptr [stack_pointer]
  1341.                 mov ax,4c04h
  1342.  
  1343.                 int 21h
  1344.  
  1345. ;***********************************************************************
  1346.  
  1347.                 ; set up the drive parameters and the parameter table
  1348.  
  1349. ;***********************************************************************
  1350.  
  1351. set_up:
  1352.                 ; check for 720K option
  1353.  
  1354.                 cmp byte ptr [cluster_720K],FALSE
  1355.  
  1356.                 je no_720K_error
  1357.  
  1358.                 cmp word ptr [binary_size],720
  1359.  
  1360.                 je no_720K_error
  1361.  
  1362.                 mov dx,offset cluster_720K_error
  1363.                 mov ah,09h
  1364.  
  1365.                 int 21h
  1366.  
  1367.                 ; set exit code to 13 (720K option on wrong disk size)
  1368.  
  1369.                 mov sp,word ptr [stack_pointer]
  1370.                 mov ax,4c0Dh
  1371.  
  1372.                 int 21h
  1373. no_720K_error:
  1374.                 ; if transfering system, check file copy buffer space
  1375.  
  1376.                 cmp byte ptr [system],1
  1377.  
  1378.                 jne cursor_off
  1379.  
  1380.                 ; calculate copy buffer size
  1381.  
  1382.                 mov ax,sp
  1383.                 cmp ax,offset file_buffer
  1384.  
  1385.                 jb no_buffer
  1386.  
  1387.                 sub ax,offset file_buffer
  1388.                 sbb ax,word ptr [stack_size]
  1389.  
  1390.                 jc no_buffer
  1391.  
  1392.                 cmp ax,word ptr [minimum_buffer]
  1393.  
  1394.                 jnb buffer_ok
  1395. no_buffer:
  1396.                 mov dx,offset buffer_space_error
  1397.                 mov ah,09h
  1398.  
  1399.                 int 21h
  1400.  
  1401.                 ; set exit code to 7 (no room for file copy buffer)
  1402.  
  1403.                 mov sp,word ptr [stack_pointer]
  1404.                 mov ax,4c07h
  1405.  
  1406.                 int 21h
  1407. buffer_ok:
  1408.                 mov word ptr [buffer_size],ax
  1409. cursor_off:
  1410.                 ; save the current cursor and then turn the cursor off
  1411.  
  1412.                 mov ah,03h
  1413.  
  1414.                 int 10h
  1415.  
  1416.                 mov word ptr [cursor],cx
  1417.                 or cx,2000h
  1418.                 mov ah,01h
  1419.  
  1420.                 int 10h
  1421.  
  1422.                 ; issue a carrriage-return / line-feed to stdout
  1423.  
  1424.                 mov dx,offset cr_lf
  1425.                 mov ah,09h
  1426.  
  1427.                 int 21h
  1428.  
  1429.                 ; save the original disk parameter table pointer
  1430.  
  1431.                 xor ax,ax
  1432.                 mov es,ax
  1433.  
  1434.                 assume es:seg_zero
  1435.  
  1436.                 mov ax,word ptr es:[0078h]
  1437.                 mov dx,word ptr es:[007ah]
  1438.                 mov word ptr [parameter_pointer],ax
  1439.                 mov word ptr [parameter_pointer+2],dx
  1440.  
  1441.                 ; save the original control-break vector
  1442.  
  1443.                 mov ax,word ptr es:[008ch]
  1444.                 mov dx,word ptr es:[008eh]
  1445.                 mov word ptr [control_break],ax
  1446.                 mov word ptr [control_break+2],dx
  1447. recursion_loop:
  1448.                 xor ax,ax
  1449.                 mov es,ax
  1450.  
  1451.                 assume es:seg_zero
  1452.  
  1453.                 ; set the disk parameter table pointer for formatting
  1454.  
  1455.                 xor ah,ah
  1456.                 mov al,byte ptr [disk_size]
  1457.                 dec ax
  1458.                 imul ax,11
  1459.  
  1460.                 cmp byte ptr [standard],1
  1461.  
  1462.                 je use_standard
  1463.  
  1464.                 add ax,offset parameter_table
  1465.  
  1466.                 jmp short use_fast
  1467. use_standard:
  1468.                 add ax,offset standard_parameter_table
  1469. use_fast:
  1470.                 mov bx,offset break_handler
  1471.                 cli
  1472.                 mov word ptr es:[0078h],ax
  1473.                 mov word ptr es:[007ah],cs
  1474.  
  1475.                 ; set the new control-break vector
  1476.  
  1477.                 mov word ptr es:[008ch],bx
  1478.                 mov word ptr es:[008eh],cs
  1479.                 sti
  1480.                 push cs
  1481.                 pop es
  1482.  
  1483.                 assume es:cseg
  1484.  
  1485.                 ; check for prompt bypass
  1486.  
  1487.                 cmp byte ptr [prompt],1
  1488.  
  1489.                 jne no_prompt
  1490.  
  1491.                 ; clear the message line
  1492.  
  1493.                 mov dx,offset clear_line
  1494.                 mov ah,09h
  1495.  
  1496.                 int 21h
  1497. eat_keystroke:
  1498.                 ; eat any pending keystrokes
  1499.  
  1500.                 mov ah,01h
  1501.  
  1502.                 int 16h
  1503.  
  1504.                 jz no_keystroke
  1505.  
  1506.                 xor ah,ah
  1507.  
  1508.                 int 16h
  1509.  
  1510.                 jmp eat_keystroke
  1511. no_keystroke:
  1512.                 ; prompt for a floppy
  1513.  
  1514.                 mov dx,offset insert_floppy
  1515.                 mov ah,09h
  1516.                 mov al,byte ptr [drive_number]
  1517.                 add al,41h
  1518.                 mov byte ptr [insert_drive],al
  1519.  
  1520.                 int 21h
  1521.  
  1522.                 ; wait for a key press
  1523.  
  1524.                 xor ah,ah
  1525.  
  1526.                 int 16h
  1527.  
  1528.                 cmp ax,CTRL_C_KEY       ; control-C
  1529.  
  1530.                 jne escape
  1531.  
  1532.                 jmp break_handler
  1533. escape:
  1534.                 cmp ax,ESC_KEY          ; escape
  1535.  
  1536.                 jne clear
  1537.  
  1538.                 jmp break_handler
  1539. clear:
  1540.                 ; clear the message line
  1541.  
  1542.                 mov dx,offset clear_line
  1543.                 mov ah,09h
  1544.  
  1545.                 int 21h
  1546. no_prompt:
  1547.                 mov dx,offset initializing
  1548.                 mov ah,09h
  1549.  
  1550.                 int 21h
  1551.  
  1552.                 ; get disk drive information
  1553.  
  1554.                 ; note: Some machines do not support this function call,
  1555.                 ;       this makes it difficult to determine if the
  1556.                 ;       requested drive and the requested disk size are
  1557.                 ;       compatible prior to attempting the format.  What
  1558.                 ;       this BIOS function should do is read the floppy
  1559.                 ;       type from the CMOS RAM, then set the registers
  1560.                 ;       as appropriate for that type.
  1561.  
  1562.                 push es
  1563.                 mov ah,08h
  1564.                 mov dl,byte ptr [drive_number]
  1565.  
  1566.                 int 13h
  1567.  
  1568.                 jnc got_drive_type
  1569.  
  1570.                 ; keep going if the bios does not support this function
  1571.  
  1572.                 cmp ah,01h
  1573.  
  1574.                 jne no_drive_type
  1575.  
  1576.                 ; get the drive type the hard way (from the CMOS RAM)
  1577.  
  1578.                 mov al,10h
  1579.                 out 70h,al
  1580.  
  1581.                 ; note: Very fast machines may need additional I/O wait
  1582.                 ;       time here. This is common on 80486 machines.
  1583.  
  1584.                 jmp short $+2
  1585.  
  1586.                 jmp short $+2
  1587.  
  1588.                 in al,71h
  1589.                 cmp dl,0
  1590.  
  1591.                 jne drive_b
  1592.  
  1593.                 and al,0f0h
  1594.                 shr al,4
  1595. drive_b:
  1596.                 and al,0fh
  1597.                 mov bl,al
  1598.                 cmp bl,1
  1599.  
  1600.                 jne not_360
  1601.  
  1602.                 mov cx,2709h
  1603.  
  1604.                 jmp short got_drive_type
  1605. not_360:
  1606.                 cmp bl,2
  1607.  
  1608.                 jne not_1200
  1609.  
  1610.                 mov cx,4f0fh
  1611.  
  1612.                 jmp short got_drive_type
  1613. not_1200:
  1614.                 cmp bl,3
  1615.  
  1616.                 jne not_720
  1617.  
  1618.                 mov cx,4f09h
  1619.  
  1620.                 jmp short got_drive_type
  1621. not_720:
  1622.                 cmp bl,4
  1623.  
  1624.                 jne not_1440
  1625.  
  1626.                 mov cx,4f12h
  1627.  
  1628.                 jmp short got_drive_type
  1629. not_1440:
  1630.                 cmp bl,5
  1631.  
  1632.                 jne not_2880
  1633.  
  1634.                 mov cx,4f24h
  1635.  
  1636.                 jmp short got_drive_type
  1637. not_2880:
  1638.                 cmp bl,0
  1639.  
  1640.                 je got_drive_type
  1641. no_drive_type:
  1642.                 mov dx,offset clear_line
  1643.                 mov ah,09h
  1644.  
  1645.                 int 21h
  1646.  
  1647.                 mov dx,offset get_type_error
  1648.                 mov ah,09h
  1649.  
  1650.                 int 21h
  1651.  
  1652.                 ; set exit code to 10 (unknown drive type)
  1653.  
  1654.                 mov ax,4c0ah
  1655.                 push ax
  1656.  
  1657.                 jmp error_exit
  1658. got_drive_type:
  1659.                 cmp bl,0
  1660.  
  1661.                 jne drive_exists
  1662.  
  1663.                 mov dx,offset clear_line
  1664.                 mov ah,09h
  1665.  
  1666.                 int 21h
  1667.  
  1668.                 mov dx,offset no_drive_error
  1669.                 mov ah,09h
  1670.  
  1671.                 int 21h
  1672.  
  1673.                 ; set exit code to 3 (drive does not exist)
  1674.  
  1675.                 mov ax,4c03h
  1676.                 push ax
  1677.  
  1678.                 jmp error_exit
  1679. drive_exists:
  1680.                 cmp bl,5
  1681.  
  1682.                 ; drive type greater than 2.88 Mb ?
  1683.  
  1684.                 jg no_drive_type
  1685.  
  1686.                 mov byte ptr [max_track],ch
  1687.                 mov byte ptr [sectors_track],cl
  1688.                 mov byte ptr [drive_type],bl
  1689.                 mov ah,byte ptr [disk_size]
  1690.                 mov al,bl
  1691.                 mov word ptr [disk_drive],ax
  1692.  
  1693.                 ; check for floppy size less than drive maximum capacity
  1694.  
  1695.                 ; check for a 360 Kb floppy in a 1.2 Mb drive
  1696.  
  1697.                 cmp word ptr [disk_drive],0102h
  1698.  
  1699.                 je forty_tracks
  1700.  
  1701.                 ; check for a 720 Kb floppy in a 1.2 Mb drive
  1702.  
  1703.                 cmp word ptr [disk_drive],0302h
  1704.  
  1705.                 je nine_sectors
  1706.  
  1707.                 ; check for a 720 Kb floppy in a 1.44 Mb drive
  1708.  
  1709.                 cmp word ptr [disk_drive],0304h
  1710.  
  1711.                 je nine_sectors
  1712.  
  1713.                 ; check for a 720 Kb floppy in a 2.88 Mb drive
  1714.  
  1715.                 cmp word ptr [disk_drive],0305h
  1716.  
  1717.                 je nine_sectors
  1718.  
  1719.                 ; check for a 1.44 Mb floppy in a 2.88 Mb drive
  1720.  
  1721.                 cmp word ptr [disk_drive],0405h
  1722.  
  1723.                 je eighteen_sectors
  1724.  
  1725.                 jmp short check_for_bad
  1726. forty_tracks:
  1727.                 mov byte ptr [max_track],39
  1728. nine_sectors:
  1729.                 mov byte ptr [sectors_track],9
  1730.  
  1731.                 jmp size_ok
  1732.  
  1733. eighteen_sectors:
  1734.  
  1735.                 mov byte ptr [sectors_track],18
  1736.  
  1737.                 jmp size_ok
  1738. check_for_bad:
  1739.                 ; check for improper disk / drive cominations
  1740.  
  1741.                 cmp word ptr [disk_drive],0201h
  1742.  
  1743.                 je bad_size                     ; 1.2 Mb in 360 Kb
  1744.  
  1745.                 cmp word ptr [disk_drive],0301h
  1746.  
  1747.                 je bad_size                     ; 720 Kb in 360 Kb
  1748.  
  1749.                 cmp word ptr [disk_drive],0401h
  1750.  
  1751.                 je bad_size                     ; 1.44 Mb in 360 Kb
  1752.  
  1753.                 cmp word ptr [disk_drive],0302h
  1754.  
  1755.                 je bad_size                     ; 720 Kb in 1.2 Mb
  1756.  
  1757.                 cmp word ptr [disk_drive],0402h
  1758.  
  1759.                 je bad_size                     ; 1.44 Mb in 1.2 Mb
  1760.  
  1761.                 cmp word ptr [disk_drive],0103h
  1762.  
  1763.                 je bad_size                     ; 360 Kb in 720 Kb
  1764.  
  1765.                 cmp word ptr [disk_drive],0203h
  1766.  
  1767.                 je bad_size                     ; 1.2 Mb in 720 Kb
  1768.  
  1769.                 cmp word ptr [disk_drive],0403h
  1770.  
  1771.                 je bad_size                     ; 1.44 Mb in 720 Kb
  1772.  
  1773.                 cmp word ptr [disk_drive],0104h
  1774.  
  1775.                 je bad_size                     ; 360 Kb in 1.44 Mb
  1776.  
  1777.                 cmp word ptr [disk_drive],0204h
  1778.  
  1779.                 je bad_size                     ; 1.2 Mb in 1.44 Mb
  1780.  
  1781.                 cmp word ptr [disk_drive],0501h
  1782.  
  1783.                 je bad_size                     ; 2.88 Mb in 360 Kb
  1784.  
  1785.                 cmp word ptr [disk_drive],0502h
  1786.  
  1787.                 je bad_size                     ; 2.88 Mb in 1.2 Mb
  1788.  
  1789.                 cmp word ptr [disk_drive],0503h
  1790.  
  1791.                 je bad_size                     ; 2.88 Mb in 720 Kb
  1792.  
  1793.                 cmp word ptr [disk_drive],0504h
  1794.  
  1795.                 je bad_size                     ; 2.88 Mb in 1.44 Mb
  1796.  
  1797.                 cmp word ptr [disk_drive],0105h
  1798.  
  1799.                 je bad_size                     ; 360 Kb in 2.88 Mb
  1800.  
  1801.                 cmp word ptr [disk_drive],0205h
  1802.  
  1803.                 je bad_size                     ; 1.2 Mb in 2.88 Mb
  1804.  
  1805.                 jmp short size_ok
  1806. bad_size:
  1807.                 mov dx,offset clear_line
  1808.                 mov ah,09h
  1809.  
  1810.                 int 21h
  1811.  
  1812.                 mov dx,offset set_disk_error
  1813.                 mov ah,09h
  1814.  
  1815.                 int 21h
  1816.  
  1817.                 ; set exit code to 2 (disk / drive comination error)
  1818.  
  1819.                 mov ax,4c02h
  1820.                 push ax
  1821.  
  1822.                 jmp error_exit
  1823. size_ok:
  1824.                 ; put the parameter table in the boot record
  1825.  
  1826.                 pop es
  1827.                 xor ah,ah
  1828.                 mov al,byte ptr [disk_size]
  1829.                 dec ax
  1830.                 imul ax,11
  1831.                 add ax,offset parameter_table
  1832.                 mov si,ax
  1833.                 mov di,offset disk_table
  1834.                 mov cx,11
  1835.                 cld
  1836.  
  1837.                 rep movsb
  1838.  
  1839. ;***********************************************************************
  1840.  
  1841.                 ; store the disk parameters in the boot record and FAT
  1842.  
  1843. ;***********************************************************************
  1844.  
  1845.                 push si
  1846.  
  1847.                 ; calculate the offset to the parameters in floppy_table
  1848.  
  1849.                 xor ah,ah
  1850.                 mov al,byte ptr [disk_size]
  1851.                 dec ax
  1852.                 imul ax,10
  1853.                 mov bx,ax
  1854.                 mov si,offset floppy_table
  1855.  
  1856.                 cmp byte ptr [cluster_720K],TRUE
  1857.  
  1858.                 jne normal_720K
  1859.  
  1860.                 add si,30
  1861. normal_720K:
  1862.                 ; set the media descriptor byte
  1863.  
  1864.                 mov al,byte ptr [si+bx]
  1865.                 mov byte ptr [descriptor],al
  1866.                 mov byte ptr [fat_record],al    ; first byte of FAT
  1867.  
  1868.                 ; set the number of root directory entries
  1869.  
  1870.                 mov ax,word ptr [si+bx+4]
  1871.                 mov word ptr [directory_size],ax
  1872.  
  1873.                 ; set the number of sectors per directory
  1874.  
  1875.                 mov al,byte ptr [si+bx+6]
  1876.                 mov byte ptr [sectors_directory],al
  1877.  
  1878.                 ; set the number of sectors per cluster
  1879.  
  1880.                 mov al,byte ptr [si+bx+7]
  1881.                 mov byte ptr [sectors_cluster],al
  1882.  
  1883.                 ; set the number of sectors per FAT
  1884.  
  1885.                 mov ax,word ptr [si+bx+8]
  1886.                 mov word ptr [sectors_fat],ax
  1887.  
  1888.                 ; set the total number of sectors per disk
  1889.  
  1890.                 xor dx,dx
  1891.                 xor ah,ah
  1892.                 mov al,byte ptr [max_track]
  1893.                 inc ax
  1894.                 mul word ptr [sectors_track]
  1895.                 xor bh,bh
  1896.                 mov bl,byte ptr [heads]
  1897.                 mul bx
  1898.                 mov word ptr [small_total],ax
  1899.  
  1900.                 ; calculate the location of the first directory sector
  1901.  
  1902.                 xor dx,dx
  1903.                 xor ah,ah
  1904.                 mov al,byte ptr [fats]
  1905.                 mul word ptr [sectors_fat]
  1906.                 add ax,word ptr [hidden_sectors]
  1907.                 add ax,word ptr [reserved_sectors]
  1908.  
  1909.                 ; store directory start sector (absolute sector number)
  1910.  
  1911.                 mov word ptr [dir_start],ax
  1912.  
  1913.                 ; calculate the location of the first data sector
  1914.  
  1915.                 xor bh,bh
  1916.                 mov bl,byte ptr [sectors_directory]
  1917.                 add ax,bx
  1918.  
  1919.                 ; store data start sector (absolute sector number)
  1920.  
  1921.                 mov word ptr [data_start],ax
  1922.                 pop si
  1923.  
  1924.                 ; reset the disk controller
  1925.  
  1926.                 call reset
  1927.  
  1928.                 jnc set_drive
  1929.  
  1930.                 jmp write_error
  1931.  
  1932. ;***********************************************************************
  1933.  
  1934.                 ; set the drive type for format
  1935.  
  1936. ;***********************************************************************
  1937.  
  1938. set_drive:
  1939.                 mov byte ptr [retry_count],3
  1940. drive_retry:
  1941.                 mov al,byte ptr [drive_type]
  1942.                 cmp al,3
  1943.  
  1944.                 jl five_inch
  1945.  
  1946.                 mov al,4
  1947.  
  1948.                 jmp short set_type
  1949. five_inch:
  1950.                 cmp al,2
  1951.  
  1952.                 jne low_density
  1953.  
  1954.                 cmp byte ptr [disk_size],1
  1955.  
  1956.                 jg high_density
  1957.  
  1958.                 mov al,2
  1959.  
  1960.                 jmp short set_type
  1961. high_density:
  1962.                 mov al,3
  1963.  
  1964.                 jmp short set_type
  1965. low_density:
  1966.                 mov al,1
  1967. set_type:
  1968.                 mov ah,17h
  1969.  
  1970.                 int 13h
  1971.  
  1972.                 jnc short set_disk
  1973.  
  1974.                 cmp ah,80h
  1975.  
  1976.                 jne floppy_exists
  1977.  
  1978.                 mov dx,offset no_floppy_error
  1979.  
  1980.                 jmp write_error
  1981. floppy_exists:
  1982.                 ; keep going if the bios does not support this function
  1983.  
  1984.                 cmp ah,01h
  1985.  
  1986.                 je set_disk
  1987.  
  1988.                 ; reset the disk controller
  1989.  
  1990.                 call reset
  1991.  
  1992.                 dec byte ptr [retry_count]
  1993.  
  1994.                 jnz drive_retry
  1995.  
  1996.                 mov dx,offset set_drive_error
  1997.  
  1998.                 jmp write_error
  1999.  
  2000. ;***********************************************************************
  2001.  
  2002.                 ; set the disk type for format
  2003.  
  2004. ;***********************************************************************
  2005.  
  2006. set_disk:
  2007.                 mov byte ptr [retry_count],3
  2008. disk_retry:
  2009.                 push es
  2010.                 push di
  2011.                 mov ah,18h
  2012.                 mov ch,byte ptr [max_track]
  2013.                 mov cl,byte ptr [sectors_track]
  2014.                 mov dl,byte ptr [drive_number]
  2015.  
  2016.                 int 13h
  2017.  
  2018.                 pop di
  2019.                 pop es
  2020.  
  2021.                 jnc format_disk
  2022.  
  2023.                 ; keep going if the bios does not support this function
  2024.  
  2025.                 cmp ah,01h
  2026.  
  2027.                 je format_disk
  2028.  
  2029.                 ; reset the disk controller
  2030.  
  2031.                 call reset
  2032.  
  2033.                 dec byte ptr [retry_count]
  2034.  
  2035.                 jnz disk_retry
  2036.  
  2037.                 mov dx,offset set_disk_error
  2038.  
  2039.                 jmp write_error
  2040.  
  2041. ;***********************************************************************
  2042.  
  2043.                 ; format the disk
  2044.  
  2045. ;***********************************************************************
  2046.  
  2047. format_disk:
  2048.                 ; start at track zero
  2049.  
  2050.                 call track_zero
  2051.  
  2052.                 ; set up the loop counter
  2053.  
  2054.                 xor ch,ch
  2055.                 mov cl,byte ptr [max_track]
  2056.                 inc cx
  2057. format_loop:
  2058.                 cmp byte ptr [prompt],TRUE
  2059.  
  2060.                 jne no_key_ready
  2061.  
  2062.                 ; check for pending keystrokes
  2063.  
  2064.                 mov ah,01h
  2065.  
  2066.                 int 16h
  2067.  
  2068.                 jz no_key_ready
  2069.  
  2070.                 xor ah,ah
  2071.  
  2072.                 int 16h
  2073.  
  2074.                 cmp ax,CTRL_C_KEY       ; control-C
  2075.  
  2076.                 jne not_Ctrl_C
  2077.  
  2078.                 jmp break_handler
  2079. not_Ctrl_C:
  2080.                 cmp ax,ESC_KEY          ; escape
  2081.  
  2082.                 jne format_loop
  2083.  
  2084.                 jmp break_handler
  2085. no_key_ready:
  2086.                 push cx
  2087.  
  2088.                 call format_track
  2089.  
  2090.                 jnc continue
  2091.  
  2092.                 pop cx
  2093.  
  2094.                 jmp write_error
  2095. continue:
  2096.                 call next_track
  2097.  
  2098.                 pop cx
  2099.  
  2100.                 loop format_loop
  2101.  
  2102. ;***********************************************************************
  2103.  
  2104.                 ; set up the volume serial number in the boot record
  2105.  
  2106. ;***********************************************************************
  2107.  
  2108.                 cmp byte ptr [unix],1
  2109.  
  2110.                 jne serial_number
  2111.  
  2112.                 jmp exit
  2113. serial_number:
  2114.                 ; the disk serial number is a four byte number made up
  2115.                 ; from the system clock as follows :
  2116.  
  2117.                 ; byte 0 = day + hundredths of a second
  2118.                 ; byte 1 = month + second
  2119.                 ; byte 2 = low byte of year + minute
  2120.                 ; byte 3 = high byte of year + hour
  2121.  
  2122.                 ; this method of serial number generation makes the
  2123.                 ; possibility of duplicate serial numbers occuring
  2124.                 ; extremely low, but not impossible
  2125.  
  2126.                 ; get the system time
  2127.  
  2128.                 mov ah,2ch
  2129.  
  2130.                 int 21h
  2131.  
  2132.                 push dx
  2133.                 push cx
  2134.  
  2135.                 ; get the system date
  2136.  
  2137.                 mov ah,2ah
  2138.  
  2139.                 int 21h
  2140.  
  2141.                 pop ax
  2142.                 add cx,ax
  2143.  
  2144.                 pop ax
  2145.                 add dx,ax
  2146.  
  2147.                 ; store the serial number in the boot record
  2148.  
  2149.                 mov word ptr [sn_low],cx
  2150.                 mov word ptr [sn_high],dx
  2151.  
  2152. ;***********************************************************************
  2153.  
  2154.                 ; set up the system file names in the boot record
  2155.  
  2156. ;***********************************************************************
  2157.  
  2158.                 ; get default drive
  2159.  
  2160.                 mov ah,19h
  2161.  
  2162.                 int 21h
  2163.  
  2164.                 ; set source drive
  2165.  
  2166.                 add al,41h
  2167.                 mov byte ptr [ibm_bios_source_path],al
  2168.                 mov byte ptr [ms_bios_source_path],al
  2169.  
  2170.                 ; attempt to open IO.SYS
  2171.  
  2172.                 mov dx,offset ms_bios_source_path
  2173.                 xor al,al
  2174.                 mov ah,3dh
  2175.  
  2176.                 int 21h
  2177.  
  2178.                 jnc found_ms
  2179.  
  2180.                 ; attempt to open IBMBIO.COM
  2181.  
  2182.                 mov dx,offset ibm_bios_source_path
  2183.                 xor al,al
  2184.                 mov ah,3dh
  2185.  
  2186.                 int 21h
  2187.  
  2188.                 jnc found_ibm
  2189.  
  2190.                 ; no system on default drive
  2191.  
  2192.                 mov byte ptr [system_exists],FALSE
  2193.  
  2194.                 jmp short write_boot
  2195. found_ms:
  2196.                 ; close the file
  2197.  
  2198.                 mov bx,ax
  2199.                 mov ah,3eh
  2200.  
  2201.                 int 21h
  2202.  
  2203.                 mov byte ptr [system_exists],TRUE
  2204.                 mov byte ptr [is_ibm],FALSE
  2205.  
  2206.                 ; fix the bios name in the boot record
  2207.  
  2208.                 mov cx,11
  2209.                 mov si,offset ms_bios_name
  2210.                 mov di,offset bios_name
  2211.                 cld
  2212.  
  2213.                 rep movsb
  2214.  
  2215.                 mov cx,11
  2216.                 mov si,offset ms_dos_name
  2217.                 mov di,offset dos_name
  2218.                 cld
  2219.  
  2220.                 rep movsb
  2221.  
  2222.                 jmp short write_boot
  2223. found_ibm:
  2224.                 ; close the file
  2225.  
  2226.                 mov bx,ax
  2227.                 mov ah,3eh
  2228.  
  2229.                 int 21h
  2230.  
  2231.                 mov byte ptr [system_exists],TRUE
  2232.                 mov byte ptr [is_ibm],TRUE
  2233.  
  2234.                 ; fix the bios name in the boot record
  2235.  
  2236.                 mov cx,11
  2237.                 mov si,offset ibm_bios_name
  2238.                 mov di,offset bios_name
  2239.                 cld
  2240.  
  2241.                 rep movsb
  2242.  
  2243.                 mov cx,11
  2244.                 mov si,offset ibm_dos_name
  2245.                 mov di,offset dos_name
  2246.                 cld
  2247.  
  2248.                 rep movsb
  2249.  
  2250. ;***********************************************************************
  2251.  
  2252.                 ; write the boot record and FAT1
  2253.  
  2254. ;***********************************************************************
  2255.  
  2256. write_boot:
  2257.                 mov dx,offset boot_message
  2258.                 mov ah,09h
  2259.  
  2260.                 int 21h
  2261.  
  2262.                 mov byte ptr [retry_count],3
  2263. boot_retry:
  2264.                 mov ax,0302h
  2265.                 mov bx,offset DOS_boot
  2266.                 mov cx,0001h
  2267.                 xor dh,dh
  2268.                 mov dl,byte ptr [drive_number]
  2269.  
  2270.                 int 13h
  2271.  
  2272.                 jnc short finish_fat1
  2273.  
  2274.                 ; reset the disk controller
  2275.  
  2276.                 call reset
  2277.  
  2278.                 dec byte ptr [retry_count]
  2279.  
  2280.                 jnz boot_retry
  2281.  
  2282.                 mov dx,offset write_boot_error
  2283.  
  2284.                 jmp write_error
  2285. finish_fat1:
  2286.                 mov dx,offset fat_message
  2287.                 mov ah,09h
  2288.  
  2289.                 int 21h
  2290.  
  2291.                 ; set the starting sector (absolute)
  2292.  
  2293.                 mov ax,2
  2294.  
  2295.                 ; set the number of sectors to write
  2296.  
  2297.                 mov cx,word ptr [sectors_fat]
  2298.                 dec cx
  2299. fat1:
  2300.                 push ax
  2301.                 push cx
  2302.                 push dx
  2303.  
  2304.                 call write_ths
  2305.  
  2306.                 mov bx,offset fat_dir_record
  2307.                 mov byte ptr [retry_count],3
  2308. fat1_retry:
  2309.                 call write_disk
  2310.  
  2311.                 jnc fat1_write_ok
  2312.  
  2313.                 ; reset the disk controller
  2314.  
  2315.                 call reset
  2316.  
  2317.                 dec byte ptr [retry_count]
  2318.  
  2319.                 jnz fat1_retry
  2320.  
  2321.                 pop ax
  2322.                 pop ax
  2323.                 pop ax
  2324.  
  2325.                 mov dx,offset write_fat_error
  2326.  
  2327.                 jmp write_error
  2328. fat1_write_ok:
  2329.                 pop dx
  2330.                 pop cx
  2331.                 pop ax
  2332.  
  2333.                 ; increment the absolute sector number
  2334.  
  2335.                 add ax,1
  2336.  
  2337.                 loop fat1
  2338.  
  2339.                 jnc write_fat
  2340.  
  2341.                 mov dx,offset write_fat_error
  2342.  
  2343.                 jmp write_error
  2344.  
  2345. ;***********************************************************************
  2346.  
  2347.                 ; write FAT2
  2348.  
  2349. ;***********************************************************************
  2350.  
  2351. write_fat:
  2352.                 mov byte ptr [retry_count],3
  2353. fat_retry:
  2354.                 mov ax,0301h
  2355.                 mov bx,offset fat_record
  2356.                 xor ch,ch
  2357.                 mov cl,byte ptr [sectors_fat]
  2358.                 add cl,2
  2359.                 xor dh,dh
  2360.                 mov dl,byte ptr [drive_number]
  2361.  
  2362.                 int 13h
  2363.  
  2364.                 jnc finish_fat2
  2365.  
  2366.                 ; reset the disk controller
  2367.  
  2368.                 call reset
  2369.  
  2370.                 dec byte ptr [retry_count]
  2371.  
  2372.                 jnz fat_retry
  2373.  
  2374.                 mov dx,offset write_fat_error
  2375.  
  2376.                 jmp write_error
  2377. finish_fat2:
  2378.                 ; set the starting sector (absolute)
  2379.  
  2380.                 mov ax,2
  2381.                 add ax,word ptr [sectors_fat]
  2382.  
  2383.                 ; set the number of sectors to write
  2384.  
  2385.                 mov cx,word ptr [sectors_fat]
  2386.                 dec cx
  2387. fat2:
  2388.                 push ax
  2389.                 push cx
  2390.                 push dx
  2391.  
  2392.                 call write_ths
  2393.  
  2394.                 mov bx,offset fat_dir_record
  2395.                 mov byte ptr [retry_count],3
  2396. fat2_retry:
  2397.                 call write_disk
  2398.  
  2399.                 jnc fat2_write_ok
  2400.  
  2401.                 ; reset the disk controller
  2402.  
  2403.                 call reset
  2404.  
  2405.                 dec byte ptr [retry_count]
  2406.  
  2407.                 jnz fat2_retry
  2408.  
  2409.                 pop ax
  2410.                 pop ax
  2411.                 pop ax
  2412.  
  2413.                 mov dx,offset write_fat_error
  2414.  
  2415.                 jmp write_error
  2416. fat2_write_ok:
  2417.                 pop dx
  2418.                 pop cx
  2419.                 pop ax
  2420.  
  2421.                 ; increment the absolute sector number
  2422.  
  2423.                 add ax,1
  2424.  
  2425.                 loop fat2
  2426.  
  2427.                 jnc write_dir
  2428.  
  2429.                 mov dx,offset write_fat_error
  2430.  
  2431.                 jmp write_error
  2432.  
  2433. ;***********************************************************************
  2434.  
  2435.                 ; write the root directory
  2436.  
  2437. ;***********************************************************************
  2438.  
  2439. write_dir:
  2440.                 mov dx,offset dir_message
  2441.                 mov ah,09h
  2442.  
  2443.                 int 21h
  2444.  
  2445.                 ; set the starting sector (absolute)
  2446.  
  2447.                 mov ax,word ptr [sectors_fat]
  2448.                 mul byte ptr [fats]
  2449.                 add ax,word ptr [reserved_sectors]
  2450.  
  2451.                 ; set the number of sectors to write
  2452.  
  2453.                 xor ch,ch
  2454.                 mov cl,byte ptr [sectors_directory]
  2455. dir:
  2456.                 push ax
  2457.                 push cx
  2458.                 push dx
  2459.  
  2460.                 call write_ths
  2461.  
  2462.                 mov bx,offset fat_dir_record
  2463.                 mov byte ptr [retry_count],3
  2464. dir_retry:
  2465.                 call write_disk
  2466.  
  2467.                 jnc dir_write_ok
  2468.  
  2469.                 ; reset the disk controller
  2470.  
  2471.                 call reset
  2472.  
  2473.                 dec byte ptr [retry_count]
  2474.  
  2475.                 jnz dir_retry
  2476.  
  2477.                 pop ax
  2478.                 pop ax
  2479.                 pop ax
  2480.  
  2481.                 mov dx,offset write_dir_error
  2482.  
  2483.                 jmp short write_error
  2484. dir_write_ok:
  2485.                 pop dx
  2486.                 pop cx
  2487.                 pop ax
  2488.  
  2489.                 ; increment the absolute sector number
  2490.  
  2491.                 add ax,1
  2492.  
  2493.                 loop dir
  2494.  
  2495.                 jnc transfer
  2496.  
  2497.                 mov dx,offset write_dir_error
  2498.  
  2499.                 jmp short write_error
  2500. transfer:
  2501.                 cmp byte ptr [system],1
  2502.  
  2503.                 jne exit
  2504.  
  2505.                 cmp byte ptr [system_exists],TRUE
  2506.  
  2507.                 jne no_system
  2508.  
  2509.                 ; transfer the system files
  2510.  
  2511.                 call load_system
  2512.  
  2513.                 pushf
  2514.  
  2515.                 ; restore the original disk parameter table pointer
  2516.  
  2517.                 ; this must be done because the create file function
  2518.                 ; used in copying the system files will reset some of
  2519.                 ; the values in the floppy parameter table to their
  2520.                 ; default values. When recursive formatting is enabled,
  2521.                 ; the parameter table will be reset before each floppy.
  2522.  
  2523.                 mov cx,word ptr [parameter_pointer]
  2524.                 mov dx,word ptr [parameter_pointer+2]
  2525.                 push es
  2526.                 xor ax,ax
  2527.                 mov es,ax
  2528.  
  2529.                 assume es:seg_zero
  2530.  
  2531.                 cli
  2532.                 mov word ptr es:[0078h],cx
  2533.                 mov word ptr es:[007ah],dx
  2534.                 sti
  2535.                 pop es
  2536.  
  2537.                 assume es:cseg
  2538.  
  2539.                 popf
  2540.  
  2541.                 jnc exit
  2542. no_system:
  2543.                 ; set exit code to 5 (error copying system files)
  2544.  
  2545.                 mov ax,4c05h
  2546.                 push ax
  2547.  
  2548.                 jmp short error_exit
  2549. write_error:
  2550.                 push dx
  2551.                 mov dx,offset clear_line
  2552.                 mov ah,09h
  2553.  
  2554.                 int 21h
  2555.  
  2556.                 pop dx
  2557.                 mov ah,09h
  2558.  
  2559.                 int 21h
  2560.  
  2561.                 ; set exit code to 1 (format, verify, or write error)
  2562.  
  2563.                 mov ax,4c01h
  2564.                 push ax
  2565.  
  2566.                 cmp byte ptr [recurse],FALSE
  2567.  
  2568.                 je error_exit
  2569.  
  2570.                 pop ax
  2571.  
  2572.                 jmp recursion_loop
  2573.  
  2574. ;***********************************************************************
  2575.  
  2576.                 ; clean up and exit or recurse
  2577.  
  2578. ;***********************************************************************
  2579.  
  2580. exit:
  2581.                 cmp byte ptr [recurse],FALSE
  2582.  
  2583.                 je no_recursion
  2584.  
  2585.                 ; display format complete message
  2586.  
  2587.                 mov dx,offset exit_message
  2588.                 mov ah,09h
  2589.  
  2590.                 int 21h
  2591.  
  2592.                 jmp recursion_loop
  2593. no_recursion:
  2594.                 ; set exit code to 0 (Success)
  2595.  
  2596.                 mov ax,4c00h
  2597.                 push ax
  2598. error_exit:
  2599.                 ; restore the original disk parameter table pointer
  2600.                 ;  and the original control-break handler
  2601.  
  2602.                 mov cx,word ptr [parameter_pointer]
  2603.                 mov dx,word ptr [parameter_pointer+2]
  2604.                 push es
  2605.                 xor ax,ax
  2606.                 mov es,ax
  2607.  
  2608.                 assume es:seg_zero
  2609.  
  2610.                 mov ax,word ptr [control_break]
  2611.                 mov bx,word ptr [control_break+2]
  2612.                 cli
  2613.                 mov word ptr es:[008ch],ax
  2614.                 mov word ptr es:[008eh],bx
  2615.                 mov word ptr es:[0078h],cx
  2616.                 mov word ptr es:[007ah],dx
  2617.                 sti
  2618.                 pop es
  2619.  
  2620.                 assume es:cseg
  2621.  
  2622.                 ; reset the disk controller
  2623.  
  2624.                 call reset
  2625.  
  2626.                 pop ax
  2627.                 push ax
  2628.                 cmp al,0
  2629.  
  2630.                 jne abnormal_exit
  2631.  
  2632.                 ; display format complete message
  2633.  
  2634.                 mov dx,offset exit_message
  2635.                 mov ah,09h
  2636.  
  2637.                 int 21h
  2638. abnormal_exit:
  2639.                 ; restore the cursor
  2640.  
  2641.                 mov cx,word ptr [cursor]
  2642.                 mov ah,01h
  2643.  
  2644.                 int 10h
  2645.  
  2646.                 ; terminate with exit code (0 = Success, else = Failure)
  2647.  
  2648.                 pop ax
  2649.  
  2650.                 mov sp,word ptr [stack_pointer]
  2651.  
  2652.                 int 21h
  2653.  
  2654. ;***********************************************************************
  2655.  
  2656.                 ; format subroutines
  2657.  
  2658. ;***********************************************************************
  2659.  
  2660. ;***********************************************************************
  2661.  
  2662.                 ; reset the disk controller
  2663.  
  2664. ;***********************************************************************
  2665.  
  2666. reset:
  2667.                 mov byte ptr [reset_retry_count],3
  2668. reset_retry:
  2669.                 xor ah,ah
  2670.                 mov dl,byte ptr [drive_number]
  2671.  
  2672.                 int 13h
  2673.  
  2674.                 jnc short reset_exit
  2675.  
  2676.                 dec byte ptr [reset_retry_count]
  2677.  
  2678.                 jnz reset_retry
  2679.  
  2680.                 mov dx,offset reset_error
  2681.  
  2682.                 stc
  2683.  
  2684. reset_exit:     ret
  2685.  
  2686. ;***********************************************************************
  2687.  
  2688.                 ; control-break handler
  2689.  
  2690. ;***********************************************************************
  2691.  
  2692. break_handler:
  2693.                 ; restore the stack pointer
  2694.  
  2695.                 mov sp,word ptr [stack_pointer]
  2696.  
  2697.                 cmp ax,CTRL_C_KEY       ; control-C
  2698.  
  2699.                 je control_c
  2700.  
  2701.                 cmp ax,ESC_KEY          ; escape
  2702.  
  2703.                 je control_c
  2704.  
  2705.                 ; undo the CR-LF generated by the break
  2706.  
  2707.                 mov bh,0
  2708.                 mov ah,03h
  2709.  
  2710.                 int 10h
  2711.  
  2712.                 dec dh
  2713.                 mov dl,50
  2714.                 mov ah,02
  2715.  
  2716.                 int 10h
  2717. control_c:
  2718.                 mov dx,offset clear_line
  2719.                 mov ah,09h
  2720.  
  2721.                 int 21h
  2722.  
  2723.                 mov dx,offset user_abort
  2724.                 mov ah,09h
  2725.  
  2726.                 int 21h
  2727.  
  2728.                 mov ax,4c09h
  2729.                 push ax
  2730.  
  2731.                 jmp error_exit
  2732.  
  2733. ;***********************************************************************
  2734.  
  2735.                 ; information display during format
  2736.                 ;
  2737.                 ; input:
  2738.                 ;
  2739.                 ; al = track number
  2740.                 ; bl = head number
  2741.  
  2742. ;***********************************************************************
  2743.  
  2744. display_format:
  2745.                 xor ah,ah
  2746.                 aam
  2747.                 or ax,3030h
  2748.                 mov byte ptr [format_track_number+1],al
  2749.                 cmp ah,30h
  2750.  
  2751.                 jne format_digit
  2752.  
  2753.                 mov ah,20h
  2754. format_digit:
  2755.                 mov byte ptr [format_track_number],ah
  2756.                 mov al,bl
  2757.                 xor ah,ah
  2758.                 aam
  2759.                 or ax,3030h
  2760.                 mov byte ptr [format_head_number],al
  2761.                 mov dx,offset format_display
  2762.                 mov ah,09h
  2763.  
  2764.                 int 21h
  2765.  
  2766.                 ret
  2767.  
  2768. ;***********************************************************************
  2769.  
  2770.                 ; information display during verification
  2771.                 ;
  2772.                 ; input:
  2773.                 ;
  2774.                 ; al = track number
  2775.                 ; bl = head number
  2776.  
  2777. ;***********************************************************************
  2778.  
  2779. display_verify:
  2780.                 xor ah,ah
  2781.                 aam
  2782.                 or ax,3030h
  2783.                 mov byte ptr [verify_track_number+1],al
  2784.                 cmp ah,30h
  2785.  
  2786.                 jne verify_digit
  2787.  
  2788.                 mov ah,20h
  2789. verify_digit:
  2790.                 mov byte ptr [verify_track_number],ah
  2791.                 mov al,bl
  2792.                 xor ah,ah
  2793.                 aam
  2794.                 or ax,3030h
  2795.                 mov byte ptr [verify_head_number],al
  2796.                 mov dx,offset verify_display
  2797.                 mov ah,09h
  2798.  
  2799.                 int 21h
  2800.  
  2801.                 ret
  2802.  
  2803. ;***********************************************************************
  2804.  
  2805.                 ; set the track number in the sector tables to zero
  2806.  
  2807. ;***********************************************************************
  2808.  
  2809. track_zero:
  2810.                 xor ch,ch
  2811.                 mov cl,72
  2812.                 mov bx,offset sector_table_0
  2813. zero_counter:
  2814.                 mov byte ptr [bx],0
  2815.                 add bx,4
  2816.  
  2817.                 loop zero_counter
  2818.  
  2819.                 ret
  2820.  
  2821. ;***********************************************************************
  2822.  
  2823.                 ; increment the track number in the sector tables
  2824.  
  2825. ;***********************************************************************
  2826.  
  2827. next_track:
  2828.                 xor ch,ch
  2829.                 mov cl,72
  2830.                 mov bx,offset sector_table_0
  2831. track_counter:
  2832.                 inc byte ptr [bx]
  2833.                 add bx,4
  2834.  
  2835.                 loop track_counter
  2836.  
  2837.                 ret
  2838.  
  2839. ;***********************************************************************
  2840.  
  2841.                 ; format (and possibly verify) both heads on one track
  2842.  
  2843. ;***********************************************************************
  2844.  
  2845. format_track:
  2846.                 mov al,byte ptr [sector_table_0]
  2847.                 mov bl,0
  2848.  
  2849.                 ; display formatting message
  2850.  
  2851.                 call display_format
  2852.  
  2853.                 mov byte ptr [retry_count],3
  2854. head_0_retry:
  2855.                 mov ah,5
  2856.                 mov al,byte ptr [sectors_track]
  2857.                 mov bx,offset sector_table_0
  2858.                 mov ch,byte ptr [bx]
  2859.                 mov cl,byte ptr [bx+2]
  2860.                 mov dh,byte ptr [bx+1]
  2861.                 mov dl,byte ptr [drive_number]
  2862.                 push ax
  2863.  
  2864.                 int 13h
  2865.  
  2866.                 pop bx
  2867.                 pushf
  2868.                 and al,0
  2869.                 or al,bl
  2870.                 popf
  2871.  
  2872.                 jnc short head_0_ok
  2873.  
  2874.                 cmp ah,80h
  2875.  
  2876.                 jne no_timeout
  2877.  
  2878.                 mov dx,offset no_floppy_error
  2879.                 stc
  2880.  
  2881.                 ret
  2882. no_timeout:
  2883.                 cmp ah,03h
  2884.  
  2885.                 jne not_protected
  2886.  
  2887.                 mov dx,offset write_protect_error
  2888.                 stc
  2889.  
  2890.                 ret
  2891. not_protected:
  2892.                 ; reset the disk controller
  2893.  
  2894.                 call reset
  2895.  
  2896.                 dec byte ptr [retry_count]
  2897.  
  2898.                 jnz head_0_retry
  2899.  
  2900.                 mov dx,offset error_during_format
  2901.                 stc
  2902.  
  2903.                 ret
  2904. head_0_ok:
  2905.                 cmp byte ptr [verify],1
  2906.  
  2907.                 je verify_head_0
  2908.  
  2909.                 ; check for proper floppy type
  2910.                 ;
  2911.                 ; this is done via a verification of track 79, for head
  2912.                 ;  0 only, for all 1.2 Mb disks not being verified, and
  2913.                 ;  on track 0 head 0 only, for 360 Kb, 720 Kb, 1.44 Mb,
  2914.                 ;  and 2.88 Mb disks not being verified.
  2915.                 ;
  2916.                 ; the following combinations will fail at track 0:
  2917.                 ;
  2918.                 ; 1: trying to format a 1.2 Mb floppy to 360 Kb
  2919.                 ; 2: trying to format a 720 Kb floppy to 1.44 Mb *
  2920.                 ; 3: trying to format a 1.44 Mb floppy to 720 Kb * !
  2921.                 ; 4: trying to format a 720 Kb floppy to 2.88 Mb *
  2922.                 ; 5: trying to format a 2.88 Mb floppy to 720 Kb * !
  2923.                 ; 6: trying to format a 2.88 Mb floppy to 1.44 Mb * !
  2924.                 ;
  2925.                 ; the following combination will fail at track 79:
  2926.                 ;
  2927.                 ; 1: trying to format a 360 Kb floppy to 1.2 Mb (it will
  2928.                 ;     probably fail sooner, but it is sure to fail here)
  2929.                 ;
  2930.                 ; notes:
  2931.                 ;
  2932.                 ; * - these combinations may not fail if the drive-
  2933.                 ;      controller combination does not properly detect
  2934.                 ;      the the floppy type.
  2935.                 ;
  2936.                 ; ! - this combination may not fail in 720 Kb drives.
  2937.                 ;
  2938.                 ; While certain non-standard combinations may not fail,
  2939.                 ;  either the data on the disk may be at risk, or your
  2940.                 ;  pocketbook may suffer, if you insist on using them.
  2941.  
  2942.                 cmp byte ptr [disk_size],2
  2943.  
  2944.                 je one_point_two
  2945.  
  2946.                 cmp byte ptr [sector_table_0],0
  2947.  
  2948.                 je verify_type
  2949.  
  2950.                 jmp short format_head_1
  2951. one_point_two:
  2952.                 cmp byte ptr [sector_table_0],79
  2953.  
  2954.                 je verify_type
  2955.  
  2956.                 jmp short format_head_1
  2957. verify_type:
  2958.                 mov ah,04h
  2959.  
  2960.                 int 13h
  2961.  
  2962.                 jnc format_head_1
  2963.  
  2964.                 mov dx,offset disk_type_error
  2965.                 stc
  2966.  
  2967.                 ret
  2968. verify_head_0:
  2969.                 pushf
  2970.                 pusha
  2971.                 mov al,byte ptr [sector_table_0]
  2972.                 mov bl,0
  2973.  
  2974.                 ; display verifying message
  2975.  
  2976.                 call display_verify
  2977.  
  2978.                 popa
  2979.                 popf
  2980.                 mov ah,04h
  2981.  
  2982.                 int 13h
  2983.  
  2984.                 jnc format_head_1
  2985.  
  2986.                 mov dx,offset verify_error
  2987.                 stc
  2988.  
  2989.                 ret
  2990. format_head_1:
  2991.                 pushf
  2992.                 pusha
  2993.                 mov al,byte ptr [sector_table_0]
  2994.                 mov bl,1
  2995.  
  2996.                 ; display formatting message
  2997.  
  2998.                 call display_format
  2999.  
  3000.                 popa
  3001.                 popf
  3002.                 mov byte ptr [retry_count],3
  3003. head_1_retry:
  3004.                 mov ah,5
  3005.                 mov al,byte ptr [sectors_track]
  3006.                 mov bx,offset sector_table_1
  3007.                 mov ch,byte ptr [bx]
  3008.                 mov cl,byte ptr [bx+2]
  3009.                 mov dh,byte ptr [bx+1]
  3010.                 mov dl,byte ptr [drive_number]
  3011.                 push ax
  3012.  
  3013.                 int 13h
  3014.  
  3015.                 pop bx
  3016.                 pushf
  3017.                 and al,0
  3018.                 or al,bl
  3019.                 popf
  3020.  
  3021.                 jnc short head_1_ok
  3022.  
  3023.                 ; reset the disk controller
  3024.  
  3025.                 call reset
  3026.  
  3027.                 dec byte ptr [retry_count]
  3028.  
  3029.                 jnz head_1_retry
  3030.  
  3031.                 mov dx,offset error_during_format
  3032.                 stc
  3033.  
  3034.                 ret
  3035. head_1_ok:
  3036.                 cmp byte ptr [verify],1
  3037.  
  3038.                 je verify_head_1
  3039. format_return:
  3040.                 clc
  3041.  
  3042.                 ret
  3043. verify_head_1:
  3044.                 pushf
  3045.                 pusha
  3046.                 mov al,byte ptr [sector_table_1]
  3047.                 mov bl,1
  3048.  
  3049.                 ; display verifying message
  3050.  
  3051.                 call display_verify
  3052.  
  3053.                 popa
  3054.                 popf
  3055.                 mov ah,04h
  3056.  
  3057.                 int 13h
  3058.  
  3059.                 jnc format_return
  3060.  
  3061.                 mov dx,offset verify_error
  3062.                 stc
  3063.  
  3064.                 ret
  3065.  
  3066. ;***********************************************************************
  3067.  
  3068.                 ; calculate the track, head, and sector for a disk write
  3069.  
  3070. ;***********************************************************************
  3071.  
  3072. write_ths:
  3073.                 ; calculate the sector number
  3074.  
  3075.                 xor dx,dx
  3076.                 div word ptr [sectors_track]
  3077.                 inc dl
  3078.  
  3079.                 ; store the sector number
  3080.  
  3081.                 mov byte ptr [write_sector],dl
  3082.  
  3083.                 ; calculate the head number and the track number
  3084.  
  3085.                 xor dx,dx
  3086.                 div word ptr [heads]
  3087.  
  3088.                 ; store the head number
  3089.  
  3090.                 mov byte ptr [write_head],dl
  3091.  
  3092.                 ; store the track number
  3093.  
  3094.                 mov word ptr [write_track],ax
  3095.  
  3096.                 ret
  3097.  
  3098. ;***********************************************************************
  3099.  
  3100.                 ; write one sector to the disk
  3101.  
  3102. ;***********************************************************************
  3103.  
  3104. write_disk:
  3105.                 ; get the track number
  3106.  
  3107.                 mov dx,word ptr [write_track]
  3108.  
  3109.                 ; shift the upper 2 bits of the track number
  3110.                 ; into the upper 2 bits of the sector number
  3111.  
  3112.                 shl dh,6
  3113.  
  3114.                 ; get the sector number
  3115.  
  3116.                 or dh,byte ptr [write_sector]
  3117.  
  3118.                 mov cx,dx
  3119.                 xchg ch,cl
  3120.  
  3121.                 ; get the drive number
  3122.  
  3123.                 mov dl,byte ptr [drive_number]
  3124.  
  3125.                 ; get the head number
  3126.  
  3127.                 mov dh,byte ptr [write_head]
  3128.  
  3129.                 ; write one sector to the disk
  3130.  
  3131.                 mov ax,0301h
  3132.  
  3133.                 int 13h
  3134.  
  3135.                 ret
  3136.  
  3137. ;***********************************************************************
  3138.  
  3139.                 ; transfer the system files
  3140.  
  3141. ;***********************************************************************
  3142.  
  3143. load_system:
  3144.                 mov dx,offset file_copy_message
  3145.                 mov ah,09h
  3146.  
  3147.                 int 21h
  3148.  
  3149.                 ; get default drive
  3150.  
  3151.                 mov ah,19h
  3152.  
  3153.                 int 21h
  3154.  
  3155.                 ; set source drive
  3156.  
  3157.                 add al,41h
  3158.                 mov byte ptr [ibm_bios_source_path],al
  3159.                 mov byte ptr [ibm_dos_source_path],al
  3160.                 mov byte ptr [ms_bios_source_path],al
  3161.                 mov byte ptr [ms_dos_source_path],al
  3162.                 mov byte ptr [cmd_source_path],al
  3163.  
  3164.                 ; set destination drive
  3165.  
  3166.                 mov al,byte ptr [drive_number]
  3167.                 add al,41h
  3168.                 mov byte ptr [ibm_bios_destination_path],al
  3169.                 mov byte ptr [ibm_dos_destination_path],al
  3170.                 mov byte ptr [ms_bios_destination_path],al
  3171.                 mov byte ptr [ms_dos_destination_path],al
  3172.                 mov byte ptr [cmd_destination_path],al
  3173.  
  3174.                 ; copy the bios system file (IBMBIO.COM or IO.SYS)
  3175.  
  3176.                 cmp byte ptr [is_ibm],TRUE
  3177.  
  3178.                 jne ms_bios
  3179.  
  3180.                 mov bx,offset file_buffer
  3181.                 mov cx,word ptr [buffer_size]
  3182.                 mov si,offset ibm_bios_source_path
  3183.                 mov di,offset ibm_bios_destination_path
  3184.  
  3185.                 call file_copy
  3186.  
  3187.                 jnc copy_dos
  3188.  
  3189.                 jmp short load_error
  3190. ms_bios:
  3191.                 mov bx,offset file_buffer
  3192.                 mov cx,word ptr [buffer_size]
  3193.                 mov si,offset ms_bios_source_path
  3194.                 mov di,offset ms_bios_destination_path
  3195.  
  3196.                 call file_copy
  3197.  
  3198.                 jc load_error
  3199. copy_dos:
  3200.                 ; copy the dos system file (IBMDOS.COM or MSDOS.SYS)
  3201.  
  3202.                 cmp byte ptr [is_ibm],TRUE
  3203.  
  3204.                 jne ms_dos
  3205.  
  3206.                 mov bx,offset file_buffer
  3207.                 mov cx,word ptr [buffer_size]
  3208.                 mov si,offset ibm_dos_source_path
  3209.                 mov di,offset ibm_dos_destination_path
  3210.  
  3211.                 call file_copy
  3212.  
  3213.                 jnc copy_cmd
  3214.  
  3215.                 jmp short load_error
  3216. ms_dos:
  3217.                 mov bx,offset file_buffer
  3218.                 mov cx,word ptr [buffer_size]
  3219.                 mov si,offset ms_dos_source_path
  3220.                 mov di,offset ms_dos_destination_path
  3221.  
  3222.                 call file_copy
  3223.  
  3224.                 jc load_error
  3225. copy_cmd:
  3226.                 ; copy COMMAND.COM
  3227.  
  3228.                 mov bx,offset file_buffer
  3229.                 mov cx,word ptr [buffer_size]
  3230.                 mov si,offset cmd_source_path
  3231.                 mov di,offset cmd_destination_path
  3232.  
  3233.                 call file_copy
  3234. load_error:
  3235.                 ret
  3236.  
  3237. ;***********************************************************************
  3238.  
  3239.                 ; copy a file
  3240.                 ;
  3241.                 ; input :
  3242.                 ;
  3243.                 ;  bx = pointer to copy buffer
  3244.                 ;  cx = copy buffer size in bytes
  3245.                 ;  si = pointer to source path\filename
  3246.                 ;  di = pointer to destination path\filename
  3247.  
  3248. ;***********************************************************************
  3249.  
  3250.                 ; file copy variables
  3251.  
  3252. ;***********************************************************************
  3253.  
  3254. source:                 dw ?
  3255. destination:            dw ?
  3256. read_handle:            dw ?
  3257. write_handle:           dw ?
  3258. file_time:              dw ?
  3259. file_date               dw ?
  3260. file_attr:              dw ?
  3261. bytes_read:             dw ?
  3262. copy_buffer_size:       dw ?
  3263. copy_buffer:            dw ?
  3264.  
  3265. ;***********************************************************************
  3266.  
  3267.                 ; file copy error messages
  3268.  
  3269. ;***********************************************************************
  3270.  
  3271. file_not_found:
  3272.  
  3273.         db " - error opening input file"
  3274.         db CR,LF
  3275.         db "$"
  3276.  
  3277. file_create_error:
  3278.  
  3279.         db " - error creating output file"
  3280.         db CR,LF
  3281.         db "$"
  3282.  
  3283. file_read_error:
  3284.  
  3285.         db " - error reading file"
  3286.         db CR,LF
  3287.         db "$"
  3288.  
  3289. file_write_error:
  3290.  
  3291.         db " - error writing file"
  3292.         db CR,LF
  3293.         db "$"
  3294.  
  3295. ;***********************************************************************
  3296.  
  3297. file_copy:
  3298.                 mov word ptr [copy_buffer],bx
  3299.                 mov word ptr [copy_buffer_size],cx
  3300.                 mov word ptr [source],si
  3301.                 mov word ptr [destination],di
  3302.                 mov dx,word ptr [source]
  3303.                 mov ah,3dh
  3304.                 xor al,al
  3305.  
  3306.                 int 21h                         ; open source file
  3307.  
  3308.                 mov word ptr [read_handle],ax
  3309.  
  3310.                 jnc file_open
  3311.  
  3312.                 ; display file not found message
  3313.  
  3314.                 mov dx,offset cr_lf
  3315.  
  3316.                 call write_message
  3317.  
  3318.                 mov dx,word ptr [source]
  3319.  
  3320.                 call write_message
  3321.  
  3322.                 mov dx,offset file_not_found
  3323.  
  3324.                 call write_message
  3325.  
  3326.                 jmp load_error
  3327. file_open:
  3328.                 mov ax,5700h
  3329.                 mov bx,word ptr [read_handle]
  3330.  
  3331.                 int 21h                         ; get file time and date
  3332.  
  3333.                 mov word ptr [file_time],cx
  3334.                 mov word ptr [file_date],dx
  3335.                 mov ax,4300h
  3336.                 mov dx,word ptr [source]
  3337.  
  3338.                 int 21h                         ; get file attributes
  3339.  
  3340.                 mov word ptr [file_attr],cx
  3341.                 mov al,byte ptr [drive_number]
  3342.                 mov cx,0000h
  3343.                 mov dx,word ptr [destination]
  3344.                 mov ah,3ch
  3345.  
  3346.                 int 21h                         ; create destination
  3347.  
  3348.                 mov word ptr [write_handle],ax
  3349.  
  3350.                 jnc copy_loop
  3351.  
  3352.                 ; display file not created message
  3353.  
  3354.                 mov dx,offset cr_lf
  3355.  
  3356.                 call write_message
  3357.  
  3358.                 mov dx,word ptr [destination]
  3359.  
  3360.                 call write_message
  3361.  
  3362.                 mov dx,offset file_create_error
  3363.  
  3364.                 call write_message
  3365.  
  3366.                 jmp short copy_error
  3367. copy_loop:
  3368.                 call read_file
  3369.  
  3370.                 jnc file_read_ok
  3371.  
  3372.                 ; display file read error message
  3373.  
  3374.                 mov dx,offset cr_lf
  3375.  
  3376.                 call write_message
  3377.  
  3378.                 mov dx,word ptr [source]
  3379.  
  3380.                 call write_message
  3381.  
  3382.                 mov dx,offset file_read_error
  3383.  
  3384.                 call write_message
  3385.  
  3386.                 jmp short copy_error
  3387. file_read_ok:
  3388.                 call write_file
  3389.  
  3390.                 jnc file_write_ok
  3391.  
  3392.                 ; display file write error message
  3393.  
  3394.                 mov dx,offset cr_lf
  3395.  
  3396.                 call write_message
  3397.  
  3398.                 mov dx,word ptr [destination]
  3399.  
  3400.                 call write_message
  3401.  
  3402.                 mov dx,offset file_write_error
  3403.  
  3404.                 call write_message
  3405.  
  3406.                 jmp short copy_error
  3407. file_write_ok:
  3408.                 cmp ax,word ptr [copy_buffer_size]
  3409.  
  3410.                 je copy_loop
  3411.  
  3412.                 mov bx,word ptr [read_handle]
  3413.                 mov ah,3eh
  3414.  
  3415.                 int 21h                         ; close read_file
  3416.  
  3417.                 mov ax,5701h
  3418.                 mov bx,word ptr [write_handle]
  3419.                 mov cx,word ptr [file_time]
  3420.                 mov dx,word ptr [file_date]
  3421.  
  3422.                 int 21h                         ; set file time and date
  3423.  
  3424.                 mov bx,word ptr [write_handle]
  3425.                 mov ah,3eh
  3426.  
  3427.                 int 21h                         ; close write_file
  3428.  
  3429.                 mov ax,4301h
  3430.                 mov cx,word ptr [file_attr]
  3431.                 mov dx,word ptr [destination]
  3432.  
  3433.                 int 21h                         ; set file attributes
  3434.  
  3435.                 clc
  3436.  
  3437.                 ret
  3438. copy_error:
  3439.                 stc
  3440.  
  3441.                 ret
  3442.  
  3443. ;***********************************************************************
  3444.  
  3445.                 ; issue a file copy error message
  3446.  
  3447. ;***********************************************************************
  3448.  
  3449. write_message:
  3450.                 mov ah,09h
  3451.  
  3452.                 int 21h
  3453.  
  3454.                 ret
  3455.  
  3456. ;***********************************************************************
  3457.  
  3458.                 ; read file block into buffer
  3459.  
  3460. ;***********************************************************************
  3461.  
  3462. read_file:
  3463.                 mov cx,word ptr [copy_buffer_size]
  3464.                 mov bx,word ptr [read_handle]
  3465.                 mov dx,word ptr [copy_buffer]
  3466.                 mov ah,3fh
  3467.  
  3468.                 int 21h
  3469.  
  3470.                 mov word ptr [bytes_read],ax
  3471.  
  3472.                 ret
  3473.  
  3474. ;***********************************************************************
  3475.  
  3476.                 ; write file block from buffer
  3477.  
  3478. ;***********************************************************************
  3479.  
  3480. write_file:
  3481.                 mov cx,word ptr [bytes_read]
  3482.                 mov bx,word ptr [write_handle]
  3483.                 mov dx,word ptr [copy_buffer]
  3484.                 mov ah,40h
  3485.  
  3486.                 int 21h
  3487.  
  3488.                 ret
  3489.  
  3490. ;***********************************************************************
  3491.  
  3492.                 ; boot sector data (track 0, head 0, sector 1)
  3493.  
  3494. ;***********************************************************************
  3495.  
  3496. DOS_boot:
  3497.  
  3498. ;***********************************************************************
  3499.  
  3500. cseg            ends
  3501.  
  3502. .8086           ; enable the 8086 instruction set
  3503.  
  3504. cseg            segment
  3505.  
  3506. ;***********************************************************************
  3507.  
  3508.                 jmp boot_strap          ; skip over data areas
  3509.  
  3510. ;***********************************************************************
  3511.  
  3512.                 ; DOS disk data area
  3513.  
  3514. ;***********************************************************************
  3515.  
  3516. oem_name:               db   "MSDOS5.0" ; identify as an MSDOS 5.0 disk
  3517.  
  3518. bytes_sector:           dw   512        ; bytes per sector
  3519. sectors_cluster:        db   ?          ; filled in before writing boot
  3520. reserved_sectors:       dw   1          ; number of reserved sectors
  3521. fats:                   db   2          ; number of FATs
  3522. directory_size:         dw   ?          ; filled in before writing boot
  3523. small_total:            dw   ?          ; filled in before writing boot
  3524. descriptor:             db   ?          ; filled in before writing boot
  3525. sectors_fat:            dw   ?          ; filled in before writing boot
  3526. sectors_track:          dw   ?          ; filled in before writing boot
  3527. heads:                  dw   2          ; number of heads
  3528. hidden_sectors:         dd   0          ; number of hidden sectors
  3529. big_total:              dd   0          ; used for large partitions
  3530. physical_drive:         db   0          ; part of why only A is bootable
  3531. reserved:               db   0          ; not currently used by DOS
  3532. extended_boot:          db   029h       ; signature for DOS 4.0+ format
  3533. sn_low:                 dw   ?          ; filled in before writing boot
  3534. sn_high:                dw   ?          ; filled in before writing boot
  3535.  
  3536. volume_label:           db   "NO NAME    "
  3537.  
  3538. fat_type:               db   "FAT12   "
  3539.  
  3540. ;***********************************************************************
  3541.  
  3542.                 ; bootstrap program data area
  3543.  
  3544. ;***********************************************************************
  3545.  
  3546. sectors_directory:      db ?            ; filled in before writing boot
  3547. dir_start:              dw ?            ; filled in before writing boot
  3548. data_start:             dw ?            ; filled in before writing boot
  3549. disk_table:             db 11 dup (?)   ; filled in before writing boot
  3550. bios_name:              db 11 dup (?)   ; filled in before writing boot
  3551. dos_name:               db 11 dup (?)   ; filled in before writing boot
  3552. track:                  dw ?            ; bootstrap program variable
  3553. head:                   db ?            ; bootstrap program variable
  3554. sector:                 db ?            ; bootstrap program variable
  3555.  
  3556. ;***********************************************************************
  3557.  
  3558.                 ; bootstrap program error messages
  3559.  
  3560. ;***********************************************************************
  3561.  
  3562. reset_message:
  3563.                         db CR,LF,LF
  3564.                         db "Disk controller error,"
  3565.                         db NULL
  3566. read_message:
  3567.                         db CR,LF,LF
  3568.                         db "Disk read error,"
  3569.                         db NULL
  3570. system_message:
  3571.                         db CR,LF,LF
  3572.                         db "No system on disk,"
  3573.                         db NULL
  3574. retry_message:
  3575.                         db CR,LF
  3576.                         db "Press any key to reboot."
  3577.                         db NULL
  3578.  
  3579. ;***********************************************************************
  3580.  
  3581.                 ; bootstrap program code
  3582.  
  3583. ;***********************************************************************
  3584.  
  3585. boot_strap:
  3586.                 ; disable interrupts while modifying segment registers
  3587.  
  3588.                 cli
  3589.  
  3590.                 ; set the stack segment and the extra segment to 0000
  3591.  
  3592.                 xor ax,ax
  3593.                 mov es,ax
  3594.                 mov ss,ax
  3595.  
  3596.                 assume es:seg_zero,ss:seg_zero
  3597.  
  3598.                 ; DOS loads the boot record at 0000:7c00,
  3599.                 ; so put the stack just below it
  3600.  
  3601.                 mov sp,BOOT
  3602.  
  3603.                 ; set up the parameters used by the BIOS program loader
  3604.  
  3605.                 push cs
  3606.                 pop ds
  3607.                 mov si,offset disk_table
  3608.                 mov bx,0078h
  3609.  
  3610.                 ; push the BIOS program loader variables onto the stack
  3611.  
  3612.                 push ds ; ds:si points to the disk parameter table
  3613.                 push si
  3614.                 push ss ; ss:bx points to interrupt vector 0eh
  3615.                 push bx
  3616.  
  3617.                 ; set the data segment to 0000
  3618.  
  3619.                 mov ds,ax
  3620.  
  3621.                 assume ds:seg_zero
  3622.  
  3623.                 ; use the disk parameter table in the floppy boot record
  3624.  
  3625.                 mov word ptr [bx],BOOT+offset disk_table-offset DOS_boot
  3626.                 mov word ptr [bx+02],ax
  3627.  
  3628.                 ; enable interrupts
  3629.  
  3630.                 sti
  3631.  
  3632.                 ; reset the disk controller
  3633.  
  3634.                 int 13h
  3635.  
  3636.                 jnc reset_ok
  3637.  
  3638.                 ; display reset error message
  3639.  
  3640.                 mov si,BOOT+offset reset_message-offset DOS_boot
  3641.  
  3642.                 call write_string
  3643.  
  3644.                 jmp short not_bootable
  3645. reset_ok:
  3646.                 ; check for system name in boot record
  3647.  
  3648.                 cmp byte ptr ds:[BOOT+bios_name-DOS_boot],0
  3649.  
  3650.                 je system_error
  3651.  
  3652.                 ; get directory start sector (absolute sector number)
  3653.  
  3654.                 mov ax,word ptr ds:[BOOT+dir_start-DOS_boot]
  3655.  
  3656.                 ; get track, head, and sector
  3657.  
  3658.                 call calculate_ths
  3659.  
  3660.                 ; set the offset of the disk read buffer
  3661.  
  3662.                 mov bx,0500h
  3663.  
  3664.                 ; read the first directory sector
  3665.  
  3666.                 call read_disk
  3667.  
  3668.                 jc read_error
  3669.  
  3670.                 ; check directory for the BIOS file
  3671.                 ; (it must be the first directory entry)
  3672.  
  3673.                 mov di,bx
  3674.                 mov cx,11
  3675.                 mov si,BOOT+offset bios_name-offset DOS_boot
  3676.  
  3677.                 rep cmpsb
  3678.  
  3679.                 jnz system_error
  3680.  
  3681.                 ; check directory for the DOS file
  3682.                 ; (it must be the second directory entry)
  3683.  
  3684.                 lea di,[bx+32]
  3685.                 mov si,BOOT+offset dos_name-offset DOS_boot
  3686.                 mov cx,11
  3687.  
  3688.                 rep cmpsb
  3689.  
  3690.                 jnz system_error
  3691.  
  3692. ;***********************************************************************
  3693.  
  3694. system_found:
  3695.                 ; valid directory, attempt to boot from the disk
  3696.  
  3697.                 ; get the data start sector (absolute sector number)
  3698.  
  3699.                 mov ax,word ptr ds:[BOOT+data_start-DOS_boot]
  3700.  
  3701.                 ; set the offset of the disk read buffer
  3702.  
  3703.                 mov bx,0700h
  3704.  
  3705.                 ; read 3 sectors (the length of the BIOS program loader)
  3706.  
  3707.                 mov cx,3
  3708. read_next:
  3709.                 push ax
  3710.                 push cx
  3711.                 push dx
  3712.  
  3713.                 ; get track, head, and sector
  3714.  
  3715.                 call calculate_ths
  3716.  
  3717.                 ; read one disk sector
  3718.  
  3719.                 call read_disk
  3720.  
  3721.                 pop dx
  3722.                 pop cx
  3723.                 pop ax
  3724.  
  3725.                 jc read_error
  3726. disk_read_ok:
  3727.                 ; increment the sector to read
  3728.  
  3729.                 inc ax
  3730.  
  3731.                 ; bump the offset of the read buffer by the sector size
  3732.  
  3733.                 add bx,word ptr ds:[BOOT+bytes_sector-DOS_boot]
  3734.  
  3735.                 loop read_next
  3736.  
  3737.                 ; set up the parameters for the BIOS program loader
  3738.  
  3739.                 ; get the media descriptor
  3740.  
  3741.                 mov ch,byte ptr ds:[BOOT+descriptor-DOS_boot]
  3742.  
  3743.                 ; get the drive number
  3744.  
  3745.                 mov dl,byte ptr ds:[BOOT+physical_drive-DOS_boot]
  3746.  
  3747.                 ; get the data start sector (absolute sector number)
  3748.  
  3749.                 xor ax,ax
  3750.                 mov bx,word ptr ds:[BOOT+data_start-DOS_boot]
  3751.  
  3752.                 ; execute the BIOS program loader
  3753.  
  3754.                 jmp far ptr program_loader
  3755.  
  3756. ;***********************************************************************
  3757.  
  3758. not_bootable:
  3759.                 ; display retry message
  3760.  
  3761.                 mov si,BOOT+offset retry_message-offset DOS_boot
  3762.  
  3763.                 call write_string
  3764.  
  3765.                 ; wait for a key to be pressed
  3766.  
  3767.                 xor ah,ah
  3768.  
  3769.                 int 16h
  3770.  
  3771.                 ; clean up the stack
  3772.  
  3773.                 pop si
  3774.                 pop ds
  3775.                 pop [si]
  3776.                 pop [si+2]
  3777.  
  3778.                 ; try to boot the system again
  3779.  
  3780.                 int 19h
  3781.  
  3782. ;***********************************************************************
  3783.  
  3784. system_error:
  3785.                 ; display the no system error message
  3786.  
  3787.                 mov si,BOOT+offset system_message-offset DOS_boot
  3788.  
  3789.                 call write_string
  3790.  
  3791.                 jmp not_bootable
  3792.  
  3793. ;***********************************************************************
  3794.  
  3795. read_error:
  3796.                 ; display the disk read error message
  3797.  
  3798.                 mov si,BOOT+offset read_message-offset DOS_boot
  3799.  
  3800.                 call write_string
  3801.  
  3802.                 jmp not_bootable
  3803.  
  3804. ;***********************************************************************
  3805.  
  3806.                 ; bootstrap subroutines
  3807.  
  3808. ;***********************************************************************
  3809.  
  3810. ;***********************************************************************
  3811.  
  3812.                 ; write a message to the screen
  3813.  
  3814. ;***********************************************************************
  3815.  
  3816. write_string:
  3817.                 ; get one character
  3818.  
  3819.                 lodsb
  3820.  
  3821.                 ; check for end of ASCIIZ string
  3822.  
  3823.                 or al,al
  3824.  
  3825.                 jnz next_char
  3826.  
  3827.                 ret
  3828. next_char:
  3829.                 ; write one character to the screen
  3830.  
  3831.                 mov ah,0eh
  3832.  
  3833.                 ; use video page 0, normal white text
  3834.  
  3835.                 mov bx,0007h
  3836.  
  3837.                 int 10h
  3838.  
  3839.                 jmp write_string
  3840.  
  3841. ;***********************************************************************
  3842.  
  3843.                 ; read a sector from the disk
  3844.  
  3845. ;***********************************************************************
  3846.  
  3847. read_disk:
  3848.                 ; get the track number
  3849.  
  3850.                 mov dx,word ptr ds:[BOOT+track-DOS_boot]
  3851.  
  3852.                 ; shift the upper 2 bits of the track number
  3853.                 ; into the upper 2 bits of the sector number
  3854.  
  3855.                 mov cl,06
  3856.                 shl dh,cl
  3857.  
  3858.                 ; get the sector number
  3859.  
  3860.                 or dh,byte ptr ds:[BOOT+sector-DOS_boot]
  3861.  
  3862.                 mov cx,dx
  3863.                 xchg ch,cl
  3864.  
  3865.                 ; get the drive number
  3866.  
  3867.                 mov dl,byte ptr ds:[BOOT+physical_drive-DOS_boot]
  3868.  
  3869.                 ; get the head number
  3870.  
  3871.                 mov dh,byte ptr ds:[BOOT+head-DOS_boot]
  3872.  
  3873.                 ; read one sector from the disk
  3874.  
  3875.                 mov ax,0201h
  3876.  
  3877.                 int 13h
  3878.  
  3879.                 ret
  3880.  
  3881. ;***********************************************************************
  3882.  
  3883.                 ; calculate the track, head, and sector numbers
  3884.  
  3885. ;***********************************************************************
  3886.  
  3887. calculate_ths:
  3888.                 ; calculate the sector number
  3889.  
  3890.                 xor dx,dx
  3891.                 div word ptr ds:[BOOT+sectors_track-DOS_boot]
  3892.                 inc dl
  3893.  
  3894.                 ; store the sector number
  3895.  
  3896.                 mov byte ptr ds:[BOOT+sector-DOS_boot],dl
  3897.  
  3898.                 ; calculate the head number and the track number
  3899.  
  3900.                 xor dx,dx
  3901.                 div word ptr ds:[BOOT+heads-DOS_boot]
  3902.  
  3903.                 ; store the head number
  3904.  
  3905.                 mov byte ptr ds:[BOOT+head-DOS_boot],dl
  3906.  
  3907.                 ; store the track number
  3908.  
  3909.                 mov word ptr ds:[BOOT+track-DOS_boot],ax
  3910.  
  3911.                 ret
  3912.  
  3913. ;***********************************************************************
  3914.  
  3915.                 ; put program information in boot record (and FMT.COM)
  3916.  
  3917. ;***********************************************************************
  3918.  
  3919. program:        db "FMT version 2.00 07-FEB-1993",NULL
  3920.  
  3921. author:         db "Written by Clair Alan Hardesty",NULL
  3922.  
  3923. ;***********************************************************************
  3924.  
  3925.                 ; adjust the boot record size to 512 bytes
  3926.  
  3927. ;***********************************************************************
  3928.  
  3929. fill:           db (512-(offset fill-offset DOS_boot)-2) dup (0)
  3930.  
  3931.                 ; note: if the boot record is too long, the assembler
  3932.                 ;       will issue an error message stating that a
  3933.                 ;       positive count is required for the dup command.
  3934.  
  3935. ;***********************************************************************
  3936.  
  3937.                 ; boot sector signature
  3938.  
  3939. ;***********************************************************************
  3940.  
  3941. signature:      dw 0AA55h
  3942.  
  3943. ;***********************************************************************
  3944.  
  3945.                 ; end of boot sector data
  3946.  
  3947. ;***********************************************************************
  3948.  
  3949. ;***********************************************************************
  3950.  
  3951.                 ; FAT and directory data
  3952.  
  3953. ;***********************************************************************
  3954.  
  3955.                 ; the first FAT sector begins with the media descriptor
  3956. fat_record:
  3957.                 db ?                    ; filled in before writing FAT
  3958.                 db 0ffh,0ffh
  3959.  
  3960.                 ; other FAT sectors and directory sectors are all zeros
  3961. fat_dir_record:
  3962.                 db 512 dup (0)
  3963.  
  3964. ;***********************************************************************
  3965.  
  3966.                 ; file copy buffer
  3967.  
  3968. ;***********************************************************************
  3969.  
  3970. file_buffer:
  3971.                 ; the system file copy buffer space starts here and
  3972.                 ; extends to the bottom of the stack.
  3973.  
  3974. cseg            ends
  3975.  
  3976. end             entry_point
  3977.  
  3978. ;***********************************************************************
  3979.  
  3980.                 ; end of Fmt.asm
  3981.  
  3982. ;***********************************************************************
  3983.